MySQL优化复杂查询NOT IN (2 SELECT WITH JOIN) WHERE

标签 mysql select join

我有以下查询:

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/

相关文章:

mysql - 尝试使用 knex 并在 where 子句中嵌入 select 来构建复杂查询

mysql - SQL - 如果不满足条件则不显示任何内容

SQL:跨两个层次结构的完全外连接

MySql count(*) 超慢并发查询

mysql - (MySQL) 如何提取里面有点(特殊字符)的json字段

javascript - 从上一个标签获取下一个标签

mysql - 对 3 个表进行 SQL 查询(计数)

linux - Bash 加入命令

mysql - 将mysql容器的日志挂载到宿主目录

sql - PGSQL 查询以在每个用户名中使用特定字母进行排序