
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中文网其他相关文章!