花费很长时间执行复杂的 mySql 查询
Taking long time executing complex mySql query
我的查询如下所示:
$result_portlist=mysql_query("
SELECT
portfolio AS the_port,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
GROUP BY portfolio
",$db);
$myrow_portlist=mysql_fetch_array($result_portlist);
if(mysql_num_rows($result_portlist)>0) {
do {
echo '<span> value1, vaule2, value3...</span>';
$result_portlist1=mysql_query("
SELECT
department AS the_department,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
AND portfolio='$myrow_portlist[the_port]'
GROUP BY department
",$db);
$myrow_portlist1=mysql_fetch_array($result_portlist1);
if (mysql_num_rows($result_portlist1)>0) {
do {
echo '<span> value1, vaule2, value3...</span>'
$result_portlist2=mysql_query("
SELECT
manager_name AS the_manager,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
AND portfolio='$myrow_portlist[the_port]'
AND department='$myrow_portlist1[the_department]'
GROUP BY manager_name
",$db);
{
do {
echo '<span> value1, vaule2, value3...</span>';
} while ($myrow_portlist2=mysql_fetch_array($result_portlist2));
}
} while ($myrow_portlist1=mysql_fetch_array($result_portlist1));
}
} while ($myrow_portlist1=mysql_fetch_array($result_portlist1));
}
因此,对于 table 的 40,000 多行以及 portfolio
+department
+manager_name
的数百种组合,此查询需要数小时才能执行。我的想法是在开始时进行一个查询,将值按 manager_name
分组,然后让 php 分组 portfolio
和 department
。创建此查询后,我的思绪刚刚爆炸,没有可用的内存来思考:)
请告诉我如何重新排列此查询或如何简化它以减少执行时间。
提前致谢。
编辑:这是图像,我的 table(带有嵌套的 tables)看起来像:
花费大量时间的原因是您正在执行大量查询...假设您有 10 个投资组合,在 10 个部门中,您将进行 100 个查询。这个数量太疯狂了,在您的情况下减少查询数量非常简单。
我会简单地在一个查询中获取所有数据,并使用带有汇总的 3 级分组依据:
$result=mysql_query("
SELECT
portfolio AS the_port,
department AS the_department,
manager_name AS the_manager,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE
CONCAT(balance, insurance)!='0'
GROUP BY
portfolio,
department,
manager_name
with ROLLUP
ORDER BY the_port,the_department,the_manager;
",$db);
echo '<table>';
while($row = mysql_fetch_assoc($result)){
if($row['the_port'] === null){
//This is the big total row... Let's skip it for now shall we?
continue;
}
echo '<tr>';
if($row['the_department'] === null){
echo '<td>Portfolio: '.$row['the_port'].'</td>';
}else{
if($row['the_manager'] === null){
echo '<td>Department: '.$row['the_port'].'</td>';
}else{
echo '<td>Manager: '.$row['the_port'].'</td>';
}
}
echo '<td>'.$row['the_balance'].'</td>';
echo '<td>'.$row['the_insurance'].'</td>';
echo '</tr>';
}
echo '</table>';
此查询将 return 所有行按投资组合分组,然后按部门分组,然后按经理分组。这将 return 从最好的点(你的第三个 while)开始的所有行,但是使用 ROLLUP
你还将按级别获得另一组的行。这就像您在同一查询中完成 GROUP BY portfolio,department
和 GROUP BY portfolio
一样。
在汇总的行中,group by省略的key的值为NULL。因此,您可以轻松查看 the_manager
,当它为空时,表示您拥有完整的部门,当 the_department
为空时,您拥有完整的投资组合。
我的查询如下所示:
$result_portlist=mysql_query("
SELECT
portfolio AS the_port,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
GROUP BY portfolio
",$db);
$myrow_portlist=mysql_fetch_array($result_portlist);
if(mysql_num_rows($result_portlist)>0) {
do {
echo '<span> value1, vaule2, value3...</span>';
$result_portlist1=mysql_query("
SELECT
department AS the_department,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
AND portfolio='$myrow_portlist[the_port]'
GROUP BY department
",$db);
$myrow_portlist1=mysql_fetch_array($result_portlist1);
if (mysql_num_rows($result_portlist1)>0) {
do {
echo '<span> value1, vaule2, value3...</span>'
$result_portlist2=mysql_query("
SELECT
manager_name AS the_manager,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
AND portfolio='$myrow_portlist[the_port]'
AND department='$myrow_portlist1[the_department]'
GROUP BY manager_name
",$db);
{
do {
echo '<span> value1, vaule2, value3...</span>';
} while ($myrow_portlist2=mysql_fetch_array($result_portlist2));
}
} while ($myrow_portlist1=mysql_fetch_array($result_portlist1));
}
} while ($myrow_portlist1=mysql_fetch_array($result_portlist1));
}
因此,对于 table 的 40,000 多行以及 portfolio
+department
+manager_name
的数百种组合,此查询需要数小时才能执行。我的想法是在开始时进行一个查询,将值按 manager_name
分组,然后让 php 分组 portfolio
和 department
。创建此查询后,我的思绪刚刚爆炸,没有可用的内存来思考:)
请告诉我如何重新排列此查询或如何简化它以减少执行时间。
提前致谢。
编辑:这是图像,我的 table(带有嵌套的 tables)看起来像:
花费大量时间的原因是您正在执行大量查询...假设您有 10 个投资组合,在 10 个部门中,您将进行 100 个查询。这个数量太疯狂了,在您的情况下减少查询数量非常简单。
我会简单地在一个查询中获取所有数据,并使用带有汇总的 3 级分组依据:
$result=mysql_query("
SELECT
portfolio AS the_port,
department AS the_department,
manager_name AS the_manager,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE
CONCAT(balance, insurance)!='0'
GROUP BY
portfolio,
department,
manager_name
with ROLLUP
ORDER BY the_port,the_department,the_manager;
",$db);
echo '<table>';
while($row = mysql_fetch_assoc($result)){
if($row['the_port'] === null){
//This is the big total row... Let's skip it for now shall we?
continue;
}
echo '<tr>';
if($row['the_department'] === null){
echo '<td>Portfolio: '.$row['the_port'].'</td>';
}else{
if($row['the_manager'] === null){
echo '<td>Department: '.$row['the_port'].'</td>';
}else{
echo '<td>Manager: '.$row['the_port'].'</td>';
}
}
echo '<td>'.$row['the_balance'].'</td>';
echo '<td>'.$row['the_insurance'].'</td>';
echo '</tr>';
}
echo '</table>';
此查询将 return 所有行按投资组合分组,然后按部门分组,然后按经理分组。这将 return 从最好的点(你的第三个 while)开始的所有行,但是使用 ROLLUP
你还将按级别获得另一组的行。这就像您在同一查询中完成 GROUP BY portfolio,department
和 GROUP BY portfolio
一样。
在汇总的行中,group by省略的key的值为NULL。因此,您可以轻松查看 the_manager
,当它为空时,表示您拥有完整的部门,当 the_department
为空时,您拥有完整的投资组合。