MySQL 查询优化以获得月度报告
Posted
技术标签:
【中文标题】MySQL 查询优化以获得月度报告【英文标题】:MySQL Query Optimization to get montly report 【发布时间】:2018-06-14 22:28:18 【问题描述】:我需要优化查询。 脚本返回一个简单的表格结果,如下所示。
我想加快结果速度,也许一种解决方案是将 montly 查询合并到一个中。
什么是快速获得listing的最佳和正确方法?
表格
YAER 2018
ID NAME JAN FEV MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
00001 PAUL OK OK OK OK - OK - - - - - -
00002 MARK OK OK OK - - - OK - - - - - -
00003 JACK OK - - - - - OK - - - - - -
more 50K lines
我的数据库很简单
USERS
user_id
user_name
DOCUMENTS
document_id
document_user_id
document_date
document_file
首先,我得到一个用户,这样
$query_users = " SELECT user_id, user_name FROM users ";
$res_users = mysqli_query($mysqli,$query_users) or die(mysqli_error($mysqli));
并用一段时间创建一个表
<table style="width:100%">
<tr>
<th>ID</th>
<th>NAME</th>
<th>JAN</th>
<th>FEB</th>
<th>MAR</th>
<th>APR</th>
<th>MAY</th>
<th>JUN</th>
<th>JUL</th>
<th>AUO</th>
<th>SEP</th>
<th>OCT</th>
<th>NOV</th>
<th>DEC</th>
</tr>
<?php
while($row = mysqli_fetch_assoc($res_users))
$user_id = $row['user_id'];
$user_name = $row['user_name'];
?>
<tr>
<td><?php echo $user_name; ?></td>
// For each month I run this query to check if user have document on year
<?
// --------------------------------------------------------------------------------------------
// GET JAN DOCS
// --------------------------------------------------------------------------------------------
$query_doc_month_01 = "
SELECT document_id, document_date,
SUM(documento_date) AS total_documents
FROM documents
WHERE document_user_id = '$user_id'
AND document_date = '$year-01-00'
LIMIT 1
";
$res_doc_month_01 = mysqli_query($mysqli,$query_doc_month_01) or die(mysqli_error($mysqli));
while($row_month_01 = mysqli_fetch_assoc($res_doc_month_01))
$document_month_01_id = $row_month_01['document_id'];
?>
<td <? if ($document_month_01 == '') echo 'bgcolor="#f1f1c1"'; ?>>
<? if ($document_month_id == '') echo '- - -'; else echo $document_month_01_id; ?>
</td>
<?php
?>
<?
// --------------------------------------------------------------------------------------------
// SAME ABOVE TO GET FEB DOCS
// SAME ABOVE TO GET MAR DOCS
// ETC ETC
// --------------------------------------------------------------------------------------------
?>
</tr>
<?php
mysqli_close($mysqli);
?>
</table>
【问题讨论】:
$year
在哪里初始化?
上一页 $year= '2018';我编辑并添加
【参考方案1】:
看起来您可以在第一个查询中使用 JOIN 并一次获取所有数据。这样您就不会在循环中执行另一个查询。
Select user_id, user_name, document_id, document_date, document_file from users u INNER JOIN documents on d.document_user_id = u.user_id order by u.user_id
如果您仍想显示没有文档的用户,请使用左连接而不是内连接。
只使用一个查询应该会快很多。您为我想要的用户设置一个 var,并在它更改时创建一个新行。
我还建议您不要在列前加上表名。在我看来这是多余的。除了 document.document_file 之外,只知道 document.file 就足够了。
手机打字,如有错误请见谅。
【讨论】:
【参考方案2】:目前你正在这样做: 查询 N 个结果 对于每 N 个结果,您将执行另一个查询,乘以 12。
这意味着您正在用大量查询请求淹没数据库。使用内连接。 这不是完整的查询,但可以帮助您入门:
SELECT u.user_id, u.user_name
FROM users U INNER JOIN documents D
ON D.document_user_id = u.user_ID
如果需要,可以使用一个或最多 12 个查询来执行此操作。
避免发出大量请求。
【讨论】:
【参考方案3】:试试这个:
SELECT user_id, user_name, YEAR(document_date) as year, MONTH(document_date) as month, COUNT(*)
FROM users
LEFT JOIN documents ON (document_user_id = user_id)
GROUP BY user_id, year, month
这应该为每个拥有一年中特定月份的文档的用户返回一行,如果没有找到任何文档,则不会返回任何内容,您可以检查并显示未返回行的空数据
【讨论】:
以上是关于MySQL 查询优化以获得月度报告的主要内容,如果未能解决你的问题,请参考以下文章