我有以下查询:
SELECT driver_id, first_name, last_name
FROM drivers
WHERE driver_id NOT IN
(SELECT DISTINCT w.driver_id from waybills w
JOIN drivers d ON d.driver_id = w.driver_id
WHERE w.waybill_owner = 1
AND w.waybill_status = 'dispatched'
AND w.delivery_date = '2014-10-28')
AND driver_id NOT IN
(SELECT DISTINCT wm.driver_id from waybill_movements wm
JOIN drivers d ON d.driver_id = wm.driver_id
WHERE wm.movement_owner = 1
AND wm.delivery_date = '2014-10-28')
AND status = 'active'
AND driver_owner = 1
ORDER BY last_name ASC
如何优化该查询?
查询运行良好并返回预期结果,但我的问题是查询是否可以优化。
非常感谢您的时间和帮助。
更新:
是的,我有这些索引:
运单(运单所有者、运单状态、w.delivery_date) waybill_movements(wm.movement_owner,delivery_date) drivers(driver_id 主键和 drivers(status, driver_owner)
表结构不需要优化
没想到会有这么多答案。谢谢大家。
最佳答案
这取决于 is
的定义是什么。您可能需要将这些 WHERE IN
子查询重写到您的 FROM
子句中,然后针对该子查询运行现有查询,并查看 MySQL 解释是否给出了不同的执行路径和统计数据。
毫无疑问会的,因为您几乎必须在现有查询中点击 drivers
表三次才能获得您想要的结果。这是完全不必要的开销。
SELECT d.driver_id, d.first_name, d.last_name
FROM drivers d
LEFT OUTER JOIN waybills w ON
d.driver_id = w.driver_id AND
w.waybill_owner = 1 AND
w.waybill_status = 'dispatched' AND
w.delivery_date = '2014-10-28'
LEFT OUTER JOIN waybill_movements wm ON
d.driver_id = wm.driver_id AND
wm.movement_owner = 1 AND
wm.delivery_date = '2014-10-28')
WHERE
w.driver_id IS NULL AND
wm.driver_id IS NULL AND
d.status = 'active' AND
d.driver_owner = 1
ORDER BY last_name ASC
您的 ORDER BY
也一如既往地昂贵。如果不需要,那么删除它可能是个好主意。
你可能想通过解释运行@StuartLC建议的SQL和这个SQL,看看MySQL更喜欢其中任何一个。你可能会发现他的结果更好,但有时这就像抛硬币一样。 MySQL 对于派生表的处理速度通常不是非常快,因此将尽可能多的内容塞入传统连接中可以产生更好的结果。但这完全取决于表的大小,它们是否有适当的索引和所有有趣的东西。
关于MySQL优化复杂查询NOT IN (2 SELECT WITH JOIN) WHERE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26609449/