我有以下 3 个表:
- giveaway_steps_done
- giveaways_entries
- giveaway_steps
giveaway_steps_done
id step_unique_alone
giveaways_entries
id giveaway_step_unique
giveaway_steps
id step_unique_alone
查询列出giveaway_steps
中的所有记录,然后根据step_unique_alone
对giveaway_steps_done
条记录进行计数。之后,它根据giveaway_step_unique
计算giveaways_entries
记录。
SQL 查询运行良好,但方式不正确,因为执行和显示需要 30 秒。
giveaway_steps_done
有 7000 条记录。giveaways_entries
有 6800 条记录。giveaway_steps
有 170 条记录。
查询:
SELECT giveaway_steps.*,
Count(DISTINCT giveaway_steps_done.id) AS total_steps_count,
Count(DISTINCT giveaways_entries.id) AS total_steps_correct_count
FROM giveaway_steps
LEFT JOIN giveaway_steps_done
ON ( giveaway_steps_done.step_unique_alone =
giveaway_steps.step_unique_alone )
LEFT JOIN giveaways_entries
ON ( giveaways_entries.giveaway_step_unique =
giveaway_steps.step_unique_alone )
GROUP BY giveaway_steps.id
ORDER BY giveaway_steps.id DESC
样品/预期
id (giveaway_steps details) total_steps_count total_steps_correct_count
1 blabla 3 3
2 blabla 5 1
3 blabla 34 22
4 blabla 52 53
5 blabla 13 10
数据是正确的,但需要很多时间。我只是想做一个更好的时间/资源消耗查询。
如何重做问题:
- 如上所述创建三个表。
- 如上所述添加列。
- 将 10/15 条记录添加到具有不同
step_unique_alone
的giveaway_steps
。 - 将随机数据添加到其他表中,其
step_unique_alone
/giveaway_step_unique
必须与giveaway_steps
中的这些记录之一匹配。
*问题是,使用 LEFT JOIN 和 COUNT() 查询需要时间。
此 JOIN 效率低下,因为它会复制大量数据。
假设giveaway_steps.step_unique_alone
是唯一的,并且giveaway_steps_done.step_unique_alone
和giveaways_entries.giveaway_step_unique
是引用该列的外键。然后giveaway_steps_done
表中有 7000/170 行,giveaway_steps
中每行有 6800/170 行giveaways_entries
。您的 JOIN 将在每个"步骤"生成类似 (7000/170) * (6800/170) 行。总体上是 (7000/170) * (6800/170) * 170,类似于 280K 行。但即使有 280K 行,执行也不应该需要 30 秒。所以我猜你错过了支持你的连接的索引。
为了避免巨大的 JOIN,我会计算 SELECT 子句中子查询中的相关行:
SELECT giveaway_steps.*,
(
SELECT Count(giveaway_steps_done.id)
FROM giveaway_steps_done
WHERE giveaway_steps_done.step_unique_alone = giveaway_steps.step_unique_alone
) AS total_steps_count,
(
SELECT Count(giveaways_entries.id)
FROM giveaways_entries
WHERE giveaways_entries.giveaway_step_unique = giveaway_steps.step_unique_alone
) AS total_steps_correct_count
FROM giveaway_steps
ORDER BY giveaway_steps.id DESC
确保您在giveaway_steps_done.step_unique_alone
和giveaways_entries.giveaway_step_unique
上具有索引。