Subqueries with EXISTS vs IN - MySQL(EXISTS 与 IN 的子查询 - MySQL)
问题描述
以下两个查询是子查询.两者都是一样的,对我来说都很好.但问题是方法 1 查询需要大约 10 秒才能执行,而方法 2 查询需要不到 1 秒.
Below two queries are subqueries. Both are the same and both works fine for me. But the problem is Method 1 query takes about 10 secs to execute while Method 2 query takes under 1 sec.
我能够将方法 1 查询转换为方法 2,但我不明白查询中发生了什么.我一直试图自己弄清楚.我真的很想了解以下两个查询之间的区别以及性能提升是如何发生的?其背后的逻辑是什么?
I was able to convert method 1 query to method 2 but I don't understand what's happening in the query. I have been trying to figure it out myself. I would really like to learn what's the difference between below two queries and how does the performance gain happen ? what's the logic behind it ?
我不熟悉这些先进技术.我希望有人会在这里帮助我.鉴于我阅读了 docs 这并没有给我任何线索.
I'm new to these advance techniques. I hope someone will help me out here. Given that I read the docs which does not give me a clue.
方法一:
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
)
)
推荐答案
一个Explain Plan 会告诉你为什么你应该使用 Exists.通常问题来自 Exists vs Count(*).Exists 更快.为什么?
An Explain Plan would have shown you why exactly you should use Exists. Usually the question comes Exists vs Count(*). Exists is faster. Why?
关于NULL带来的挑战:当子查询返回
Null时,对于IN整个查询变成Null.所以你也需要处理它.但是使用Exist,它只是一个false.更容易应付.只是IN无法与Null比较任何东西,但Exists可以.
With regard to challenges present by NULL: when subquery returns
Null, for IN the entire query becomesNull. So you need to handle that as well. But usingExist, it's merely afalse. Much easier to cope. SimplyINcan't compare anything withNullbutExistscan.
例如Exists (Select * from yourtable where bla = 'blabla'); 当找到/匹配一个匹配时,您会得到真/假.
e.g. Exists (Select * from yourtable where bla = 'blabla'); you get true/false the moment one hit is found/matched.
在这种情况下,IN 会根据 Count(*) 的位置来选择 ALL 匹配的行,基于WHERE 因为它比较所有值.
In this case IN sort of takes the position of the Count(*) to select ALL matching rows based on the WHERE because it's comparing all values.
但也不要忘记这一点:
EXISTS对IN高速执行:当子查询结果非常大时.IN领先于EXISTS:当子查询结果非常小时.
EXISTSexecutes at high speed againstIN: when the subquery results is very large.INgets ahead ofEXISTS: when the subquery results is very small.
更多详情参考:
- 使用 IN 的子查询.
- IN - 子查询优化李>
- 加入与子查询.
这篇关于EXISTS 与 IN 的子查询 - MySQL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:EXISTS 与 IN 的子查询 - MySQL
- SQL 临时表问题 2022-01-01
- 如何使用 pip 安装 Python MySQLdb 模块? 2021-01-01
- 远程 mySQL 连接抛出“无法使用旧的不安全身份验证连接到 MySQL 4.1+"来自 XAMPP 的错误 2022-01-01
- 导入具有可变标题的 Excel 文件 2021-01-01
- 如何将 SonarQube 6.7 从 MySQL 迁移到 postgresql 2022-01-01
- 更改自动增量起始编号? 2021-01-01
- 使用 Oracle PL/SQL developer 生成测试数据 2021-01-01
- 如何将 Byte[] 插入 SQL Server VARBINARY 列 2021-01-01
- 以一个值为轴心,但将一行上的数据按另一行分组? 2022-01-01
- 在SQL中,如何为每个组选择前2行 2021-01-01
