一尘不染

EXISTS与IN的子查询-MySQL

mysql

以下两个查询是子查询。两者相同,都对我有效。但是问题是方法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
         )                                             
   )

阅读 313

收藏
2020-05-17

共1个答案

一尘不染

An Explain Plan 会告诉您为什么要使用Exists。通常问题来了Exists vs Count(*)
Exists是比较快的。为什么?

  • 关于NULL带来的挑战:当 子查询返回时Null,对于IN,整个查询变为Null。因此,您也需要处理。但是使用Exist,它只是一个false。轻松应对。根本IN无法与之相比,Null但是Exists可以。

  • 例如,Exists (Select * from yourtable where bla = 'blabla');一旦 找到/匹配匹配项, 您就会得到true / false 。

  • 在这种情况下,INsort会根据的位置Count(*)选择 所有 匹配的行,WHERE因为它正在比较所有值。

但也不要忘记这一点:

  • EXISTS``IN当子查询结果非常大时,针对:高速执行。
  • IN领先于EXISTS:子查询结果非常小时。

参考以获取更多详细信息:

2020-05-17