【发布时间】:2017-10-06 17:29:40
【问题描述】:
我知道这个问题已经被问了 100 次,这不是一个“我该怎么做”,而是一个效率问题——一个我不太了解的话题。
从我的互联网阅读中,我已经确定了一种解决最新问题的方法,听起来它非常有效 - 左连接一个“最大”表(按匹配条件分组),然后左连接匹配分组的行状况。像这样的:
Select employee.*, evaluation.* form employee
LEFT JOIN (select max(report_date) report_date, employee_id
from evaluation group by employee_id) most_recent_eval
on most_recent_eval.employee_id = employee.id
LEFT JOIN evaluation
on evaluation.employee_id = employee.id and evaluation.report_date = most_recent_eval.report_date
是否存在我不知道的问题?这是在进行 2 次表扫描(一次查找最大值,一次查找行)?是否必须对每位员工进行 2 次全面扫描?
我问的原因是,我现在正在考虑加入 3 个需要最新行(评估、安全许可和项目)的表,并且似乎任何低效率都会成倍增加。
谁能给我一些建议?
【问题讨论】:
-
您可以通过运行
explain select ...查询来了解查询在做什么。 MySQL 的网站上有详细的指导如何解释结果。如果没有解释输出,我们无法判断您的查询效率如何。 -
这是一个简化的示例,我试图不使用包含许多不相关列的实际查询的输出来掩盖问题。我真的在寻找一些关于解决“最近”连接的各种方法的效率的更一般的指导。我现在将打开关于解释输出的书籍,谢谢你的指点。
-
从查看解释结果来看,我的子查询似乎正在为派生表进行笛卡尔连接(在连接类型下显示 ALL)。我在 start_date 上有一个索引 - 不应该使用它吗?
-
我更新了我的答案以解决有关您的索引的评论。
-
删除
LEFT,除非你需要它。它可能会妨碍性能。
标签: mysql sql join query-optimization