以下两个查询是子查询。两者相同,都对我有效。但是问题是方法1的查询大约需要10秒才能执行,而方法2的查询不到1秒。
我能够将方法1的查询转换为方法2,但是我不了解查询中正在发生什么。我一直想自己弄清楚。我真的很想了解以下两个查询之间的区别是什么,以及如何获得性能提升?它背后的逻辑是什么?
我是这些高级技术的新手。我希望有人能在这里帮助我。考虑到我阅读的文档并没有给我任何提示。
方法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 ) )
方法2:
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 ) )
An Explain Plan 会告诉您为什么要使用Exists。通常问题来了Exists vs Count(*)。 Exists是比较快的。为什么?
Explain Plan
Exists
Exists vs Count(*)
关于NULL带来的挑战:当 子查询返回时Null,对于IN,整个查询变为Null。因此,您也需要处理。但是使用Exist,它只是一个false。轻松应对。根本IN无法与之相比,Null但是Exists可以。
Null
Exist
false
IN
例如,Exists (Select * from yourtable where bla = 'blabla');一旦 找到/匹配匹配项, 您就会得到true / false 。
Exists (Select * from yourtable where bla = 'blabla');
在这种情况下,INsort会根据的位置Count(*)选择 所有 匹配的行,WHERE因为它正在比较所有值。
Count(*)
WHERE
但也不要忘记这一点:
EXISTS``IN
EXISTS
参考以获取更多详细信息: