我的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'
";
}
外部查询获得1000行,内部必须计算10,000行 - 运行时间大约为115秒!有没有办法改进这个方法,使用不同的技术或组合的SQL查询?
答案 0 :(得分:2)
不要使用嵌套查询,将它们组合成一个带有连接的查询:
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
答案 1 :(得分:0)
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
在整个EXPLAIN
语句(即SELECT
)之前附加EXPLAIN SELECT count(*)...
,MySQL会给你一个关于select正在做什么的破坏。
确保begin_ymdhi字段已正确编入索引。 SHOW INDEX FROM table_2
要看。
答案 2 :(得分:0)
task_id是唯一的吗?如果是这样,那么最直接的就是:
$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);