下面两个查询是子查询。两者都是一样的,对我来说都很好。但问题是,方法1查询大约需要10秒来执行,而方法2查询需要不到1秒。
我能够将方法1查询转换为方法2,但是我不理解查询中发生了什么。我一直在尝试自己弄清楚这一点。我真的很想了解下面两个查询之间的区别,以及性能提升是如何发生的?它背后的逻辑是什么?
我对这些高级技术还很陌生。我希望有人能帮我解决这个问题。鉴于我阅读了docs,它没有给我提供线索。
方法1:
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
)
)
方法二:
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
)
)
发布于 2013-01-07 14:14:41
方法2很快,因为它使用了EXISTS
运算符,其中I MySQL
不加载任何结果。正如您的docs链接中所提到的,它省略了SELECT
子句中的所有内容。它只检查与条件匹配的第一个值,一旦找到,就设置条件TRUE
并移动以进行进一步处理。
另一方面,方法1具有IN
运算符,该运算符加载所有可能的值,然后进行匹配。只有在找到完全匹配的情况下,才会将条件设置为TRUE
,这是一个耗时的过程。
因此,您的方法2是快速的。
希望这能帮上忙。
发布于 2013-01-07 15:36:00
第二种方法速度更快,因为您的代码类似于"WHERE t3.reservation_id = t.reservation_id“。在第一种情况下,您的子查询必须对表进行全面扫描以验证信息。然而,在2o方法中,子查询确切地知道它正在寻找什么,一旦找到它,就检查having条件。
发布于 2014-04-15 22:12:24
https://stackoverflow.com/questions/14190788
复制相似问题