【问题标题】:Nested SQL query takes too long嵌套 SQL 查询耗时过长
【发布时间】:2010-10-21 13:21:36
【问题描述】:

我正在寻找一种方法来优化我拥有的一个 SQL 查询。我正在尝试获取多少具有某种类型的诗歌。

查询如下所示:

SELECT
    COUNT(*)  
FROM
    `poems`
WHERE `id` IN (    
                  SELECT `poem_id`
                  FROM `poems_genres`  
                  WHERE `genre_title` = 'derision'
              )
       AND `status` = 'finished';

这需要太长时间(大约 6-10 秒),因为它不能使用索引(我认为是因为 IN()?)。有没有办法以不同的方式重写此查询以更快地获得相同的结果?

【问题讨论】:

    标签: sql mysql query-optimization


    【解决方案1】:

    MySQL has a problemin 在其中反复重新评估不相关的子查询,就好像它们是相关的一样。重写为连接会改善事情吗?

    SELECT
        COUNT(distinct p.`id`)  
    FROM `poems` p
    JOIN `poems_genres` pg
    ON  p.`id` = pg.`poem_id`  
    WHERE pg.`genre_title` = 'derision' AND p.`status` = 'finished';
    

    如果不是,那么根据this article(请参阅“如何强制内部查询首先执行”部分)将其包装在派生表中可能会有所帮助。

    SELECT
        COUNT(*)  
    FROM
        `poems`
    WHERE `id` IN
    (
     select  `poem_id` from ( SELECT `poem_id`
                      FROM `poems_genres`  
                      WHERE `genre_title` = 'derision') x
    
    ) AND `status` = 'finished';
    

    【讨论】:

    • 谢谢,给我很多新信息 :)
    • 使用 JOIN 重写查询减少了从 4266806 到 1644 的查询检查的行。就像闪电一样工作 :)
    【解决方案2】:

    您还可以使用 EXISTS 子句并关联 id 和poem_id 字段

    SELECT
        COUNT(*)  
    FROM
        `poems` p1
    WHERE EXISTS
    (
     SELECT `poem_id`
                      FROM `poems_genres`  pg
                      WHERE `genre_title` = 'derision'  and p1.id = pg.poem_id
    
    ) AND `status` = 'finished';
    

    这和 IN 的区别在于它会尝试使用索引而不是进行全表扫描。

    【讨论】:

      猜你喜欢
      • 2013-07-24
      • 1970-01-01
      • 2015-08-19
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 2019-08-02
      相关资源
      最近更新 更多