【问题标题】:MySQL, puzzled why query is slow, have an index?MySQL,不知道为什么查询很慢,有索引吗?
【发布时间】:2011-01-18 21:15:36
【问题描述】:

我很困惑为什么我的一个查询很慢,我有索引并且我刚刚创建了一个新的。

但它仍然很慢,并出现在我的慢日志中。

这是我的问题...

  SELECT *, 
         COUNT( Word ) AS WordCount 
    FROM `keywords` 
   WHERE `LetterIdx` = 'A' 
GROUP BY Word 
ORDER BY Word;

这是查询解释

这是我的表结构和索引。

【问题讨论】:

    标签: sql mysql indexing query-optimization


    【解决方案1】:

    您可能会发现它像这样运行得更快,如果您跨 (LetterIdx, Word) 创建一个复合索引,它可能会有所帮助。这是一个 2 列索引而不是 2 个单列索引

    CREATE INDEX keywords_l_w on keywords(letterIdx, Word)
    
    SELECT Word, 
         COUNT( Word ) AS WordCount 
    FROM `keywords` 
    WHERE `LetterIdx` = 'A' 
    GROUP BY Word 
    ORDER BY Word;
    

    如果我的猜测是正确的,LetterIdx = Word 的第一个字母,这可能会更好

    # First create index on Word, then 
    SELECT Word, 
         COUNT( Word ) AS WordCount 
    FROM `keywords` 
    WHERE `Word` like 'A%' 
    GROUP BY Word 
    ORDER BY Word;
    

    至于“我很困惑为什么我的一个查询很慢,我有索引而且我刚刚创建了一个新的。”

    这是因为您要求它检索记录的所有列。这真的有必要吗?即使它可以使用索引(〜所有数据的 1/26),它仍然需要查找数据页以检索所有其他列。如果你有一个覆盖索引(letteridx,word),它就不需要返回数据。

    不管怎样,* 和 GROUP BY 在严格的 SQL 意义上并不是很好的组合。

    【讨论】:

    • 唯一的问题是,对于 LetterIdx A,我还包括数字。所以 A% 不会包括这些。您的第一个查询对速度没有任何影响。还有什么想法吗?
    • 您是否在 (letteridx, word) 上创建了索引?也有解释的机会吗?
    • 请注意,索引跨 2 列,而不是 2 个单列索引。答案已更新。仅供参考,顺序确实很重要,(Word, LI) != (LI, Word)
    【解决方案2】:

    在 (LetterIdx, Word) 上尝试复合索引

    然后它应该能够为特定的 where 子句和特定的 group by/order by 使用索引

    【讨论】:

    • 如上图所示,我已经有了 word 和 letteridx 的索引。
    • 就像cyberkiwi提到的那样,索引中列的顺序很重要。它决定了索引的物理存储方式,它决定了它可以有效使用和不能有效使用的方式。
    【解决方案3】:

    就像 Richard 所说,您应该使用带有 LetterIdx 和 Word 的复合索引。

    但我建议你做这个查询:

    SELECT Word, COUNT( * ) AS WordCount
    FROM `keywords`
    WHERE `LetterIdx` = 'A'
    GROUP BY Word
    

    由于 GROUP BY 对列进行了排序,您可以这样做:GROUP BY Word DESC 您不需要使用 ORDER BY ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 2020-10-24
      • 2021-09-04
      • 2014-09-24
      • 1970-01-01
      • 2022-12-13
      相关资源
      最近更新 更多