首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用EXISTS vs IN - MySQL的子查询

使用EXISTS vs IN - MySQL的子查询
EN

Stack Overflow用户
提问于 2013-01-07 14:08:55
回答 3查看 46.9K关注 0票数 25

下面两个查询是子查询。两者都是一样的,对我来说都很好。但问题是,方法1查询大约需要10秒来执行,而方法2查询需要不到1秒。

我能够将方法1查询转换为方法2,但是我不理解查询中发生了什么。我一直在尝试自己弄清楚这一点。我真的很想了解下面两个查询之间的区别,以及性能提升是如何发生的?它背后的逻辑是什么?

我对这些高级技术还很陌生。我希望有人能帮我解决这个问题。鉴于我阅读了docs,它没有给我提供线索。

方法1:

代码语言:javascript
复制
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 
         )
   )

方法二:

代码语言:javascript
复制
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
         )                                             
   )
EN

回答 3

Stack Overflow用户

发布于 2013-01-07 14:14:41

方法2很快,因为它使用了EXISTS运算符,其中I MySQL不加载任何结果。正如您的docs链接中所提到的,它省略了SELECT子句中的所有内容。它只检查与条件匹配的第一个值,一旦找到,就设置条件TRUE并移动以进行进一步处理。

另一方面,方法1具有IN运算符,该运算符加载所有可能的值,然后进行匹配。只有在找到完全匹配的情况下,才会将条件设置为TRUE,这是一个耗时的过程。

因此,您的方法2是快速的。

希望这能帮上忙。

票数 4
EN

Stack Overflow用户

发布于 2013-01-07 15:36:00

第二种方法速度更快,因为您的代码类似于"WHERE t3.reservation_id = t.reservation_id“。在第一种情况下,您的子查询必须对表进行全面扫描以验证信息。然而,在2o方法中,子查询确切地知道它正在寻找什么,一旦找到它,就检查having条件。

票数 0
EN

Stack Overflow用户

发布于 2014-04-15 22:12:24

他们的官方文档。SubQuery Optimization with Exists

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14190788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档