简体   繁体   English

加快SQL循环

[英]Speeding up SQL loop

I have a nested loop in my PHP code that is taking a long time and wondered of there was a way to speed this up: 我的PHP代码中有一个嵌套循环,该循环需要很长时间,并且想知道有没有一种方法可以加快速度:

$sql = "SELECT * FROM table_1";
$result = mysqli_query($sql);
while($row = mysqli_fetch_array($result)){

    $sql2 = "
    SELECT count(*) 
FROM user_modules  
WHERE 
begin_ymdhi >= ".$date_from." AND 
begin_ymdhi <= ".$date_to." AND 
(
    completed_ymdhi IS NULL OR  
    completed_ymdhi = '' 
) AND 
user_id = ".$row['user_id']." AND 
task_id = ".$row['task_id']." AND 
    module_discon = 'N' 
    ";
}

The outer query gets 1000 rows, the inner has to count across 10,000 rows - the run-time is around 115 seconds ! 外部查询获得1000行,内部查询必须跨越10,000行-运行时间约为115秒! Is there any way to improve this method, either using a different technique or combined SQL query? 是否可以使用其他方法或组合的SQL查询来改进此方法?

Don't use nested queries, combine them into a single query with a join: 不要使用嵌套查询,而是通过联接将它们组合成一个查询:

SELECT t1.*, COUNT(u.user_id) ct
FROM table_1 t1
LEFT JOIN user_modules AS u ON u.user_id = t1.user_id AND u.task_id = t1.task_id
    AND u.begin_ymdhi BETWEEN '$date_from' AND '$date_to'
    AND u.module_discon = 'N'
GROUP BY t1.user_id, t1.task_id
SELECT user_modules.user_id, user_modules.task_id, count(*) 
FROM user_modules LEFT JOIN table_1 USING (user_id, task_id) 
WHERE  
begin_ymdhi >= ".$date_from." AND 
begin_ymdhi <= ".$date_to." AND 
    module_discon = 'N' AND
(
    completed_ymdhi IS NULL OR  
    completed_ymdhi = '' 
) 
GROUP BY user_modules.user_id, user_modules.task_id

Append EXPLAIN before that entire SELECT statement (ie EXPLAIN SELECT count(*)... ) and MySQL will give you a run-down on what the select is doing. 在整个SELECT语句之前添加EXPLAIN (即EXPLAIN SELECT count(*)... ),然后MySQL将为您提供关于select所做操作的摘要。

Make sure the begin_ymdhi field is indexed properly. 确保begin_ymdhi字段已正确索引。 SHOW INDEX FROM table_2 to see. SHOW INDEX FROM table_2以查看。

Are the task_id's unique? task_id是唯一的吗? if so, the most straight forward would be something like: 如果是这样,最直接的方法将是:

 $sql2 = "
    SELECT count(task_id) AS TaskCount
FROM user_modules  
WHERE 
begin_ymdhi >= ".$date_from." AND 
begin_ymdhi <= ".$date_to." AND 
(
    completed_ymdhi IS NULL OR  
    completed_ymdhi = '' 
) AND module_discon = 'N'  
group by user_id
";

$result = mysqli_query($sql2);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM