MySQL 中使用 EXISTS 与 IN 的子查询:性能优化
在 MySQL 中使用子查询时,有两种常见的方法:使用 IN运算符并使用 EXISTS 运算符。虽然这两种方法可以实现相似的结果,但它们在性能上可能表现出显着差异。
考虑以下两个子查询示例:
方法 1 (IN):
SELECT * FROM tracker WHERE reservation_id IN ( SELECT reservation_id FROM tracker GROUP BY reservation_id HAVING ( method = 1 AND type = 0 AND Count(*) > 1 ) OR ( method = 1 AND type = 1 AND Count(*) > 1 ) OR ( method = 2 AND type = 2 AND Count(*) > 0 ) OR ( method = 3 AND type = 0 AND Count(*) > 0 ) OR ( method = 3 AND type = 1 AND Count(*) > 1 ) OR ( method = 3 AND type = 3 AND Count(*) > 0 ) )
方法2 (EXISTS):
SELECT * FROM `tracker` t WHERE EXISTS ( SELECT reservation_id FROM `tracker` t3 WHERE t3.reservation_id = t.reservation_id GROUP BY reservation_id HAVING ( METHOD = 1 AND TYPE = 0 AND COUNT(*) > 1 ) OR ( METHOD = 1 AND TYPE = 1 AND COUNT(*) > 1 ) OR ( METHOD = 2 AND TYPE = 2 AND COUNT(*) > 0 ) OR ( METHOD = 3 AND TYPE = 0 AND COUNT(*) > 0 ) OR ( METHOD = 3 AND TYPE = 1 AND COUNT(*) > 1 ) OR ( METHOD = 3 AND TYPE = 3 AND COUNT(*) > 0 ) )
如问题陈述中所述,方法 1 的执行时间明显长于方法 2。这是由于两种方法处理子查询的方式存在根本差异。
IN 运算符:
使用 IN 运算符时,MySQL 执行子查询多次,主查询中的每一行一次。在这种情况下,对于跟踪器表中的每一行,都会执行子查询来确定它是否满足指定的条件。这可能会导致显着的性能开销,特别是在子查询复杂或包含大量数据的情况下。
EXISTS 运算符:
相反,EXISTS 运算符子查询只执行一次。它检查子查询结果中是否至少有一个与主查询中的当前行匹配的行。如果存在匹配,则 EXISTS 条件被评估为 true;否则,它是错误的。这种方法效率更高,因为它避免了多次从子查询中检索所有行的需要。
在 IN 和 EXISTS 之间进行选择:
通常,它是建议尽可能使用 EXISTS 运算符,因为它在大多数情况下提供更好的性能。以下是一些指导原则,可帮助您做出正确的选择:
其他注意事项:
以上是MySQL 子查询:何时应使用 EXISTS 与 IN 以获得最佳性能?的详细内容。更多信息请关注PHP中文网其他相关文章!