我不确定我是否有正确的索引,或者我是否可以提高MySQL中查询的速度?

Jul*_*les 13 mysql sql query-optimization

我的查询有一个连接,看起来它使用两个索引,这使它更复杂.我不确定我是否能改进这一点,但我想我会问.

该查询生成一个记录列表,其中包含与要查询的记录类似的关键字.

这是我的查询.

SELECT match_keywords.padid,
       COUNT(match_keywords.word) AS matching_words
FROM   keywords current_program_keywords
       INNER JOIN keywords match_keywords
         ON match_keywords.word = current_program_keywords.word
WHERE  match_keywords.word IS NOT NULL
       AND current_program_keywords.padid = 25695
GROUP  BY match_keywords.padid
ORDER  BY matching_words DESC
LIMIT  0, 11  
Run Code Online (Sandbox Code Playgroud)

解释 替代文字

Word是varchar(40).

Ric*_*iwi 9

您可以从尝试删除IS NOT NULL测试开始,该测试由字段上的COUNT隐式删除.它看起来你想要省略25695 match_keywords,否则25695(或其他)肯定会显示为你的11行限制内的"最佳"匹配?

SELECT     match_keywords.padid,
           COUNT(match_keywords.word) AS matching_words
FROM       keywords current_program_keywords
INNER JOIN keywords match_keywords
        ON match_keywords.word = current_program_keywords.word
WHERE      current_program_keywords.padid = 25695
GROUP BY   match_keywords.padid
ORDER BY   matching_words DESC
LIMIT      0, 11
Run Code Online (Sandbox Code Playgroud)

接下来,考虑一下如何做一个人.

  • 您将以padid(25695)开头并检索该padid的所有单词
  • 从这些单词列表中,再次返回表格,对于每个匹配的单词,获取他们的padid(假设没有重复padid + word)
  • 将padid组合在一起并计算它们
  • 命令计数并返回最高11

使用3个单独的单列索引列表,前两个步骤(都只涉及2列)将始终必须从索引跳回到数据以获取另一列.覆盖索引可能会有所帮助 - 创建两个要测试的复合索引

create index ix_keyword_pw on keyword(padid, word);
create index ix_keyword_wp on keyword(word, padid);
Run Code Online (Sandbox Code Playgroud)

使用这些复合索引,您可以删除单列索引padid,word因为它们被这两个索引覆盖.

注意:您始终必须调整SELECT性能

  • 索引的大小(您创建的存储越多)
  • 插入/更新性能(索引越多,提交所需的时间越长,因为它必须更新数据,然后更新所有索引)


DRa*_*app 5

请尝试以下操作...确保PadID上的索引和WORD上的索引.然后,通过更改SELECT WHERE限定符的顺序,首先应对CURRENT关键字的PADID进行优化,然后加入其他...将连接排除到自身.此外,由于您正在检查内部联接与匹配关键字的相等性...如果检查当前关键字为null,则它应该永远不会加入空值,从而消除了对MATCH关键字别名的比较,因为查看了每个比较寻找NULL ...

SELECT STRAIGHT_JOIN
      match_keywords.padid,
      COUNT(*) AS matching_words 
   FROM
      keywords current_program_keywords
         INNER JOIN keywords match_keywords          
            ON match_keywords.word = current_program_keywords.word 
            and match_keywords.padid <> 25695
   WHERE  
          current_program_keywords.padid = 25695
      AND current_program_keywords.word IS NOT NULL
   GROUP BY 
      match_keywords.padid 
   ORDER BY 
      matching_words DESC 
   LIMIT
      0, 11 
Run Code Online (Sandbox Code Playgroud)