索引此mysql查询中的所有字段是否可以?

时间:2011-11-08 18:38:33

标签: mysql sql performance select indexing

我有这个mysql查询,我不确定索引查询中所有字段的含义是什么。我的意思是可以索引CASE语句,Join Statement和Where Statement中的所有字段吗?索引字段是否有任何性能影响?

SELECT roots.id as root_id, root_words.*,
CASE 
WHEN root_words.title LIKE '%text%' THEN 1
WHEN root_words.unsigned_title LIKE '%normalised_text%' THEN 2
WHEN unsigned_source LIKE '%normalised_text%' THEN 3
WHEN roots.root LIKE '%text%' THEN 4
END as priorities
FROM  roots INNER JOIN root_words ON roots.id=root_words.root_id
WHERE (root_words.unsigned_title LIKE '%normalised_text%') OR (root_words.title LIKE '%text%')
OR (unsigned_source LIKE '%normalised_text."%') OR (roots.root LIKE '%text%') ORDER by priorities

另外,如何进一步提高上述查询的速度?

谢谢!

4 个答案:

答案 0 :(得分:5)

  1. 您索引表中的列,而不是查询。

  2. 您指定的所有搜索条件都不能使用索引(因为搜索字词以外卡开头)。

  3. 您应确保将id列编入索引,以加快JOIN的速度。 (据推测,它已经在一个表中被索引为PRIMARY KEY而在另一个表中已被索引为外键)。

  4. 要加快此查询速度,您需要使用全文搜索。添加索引不会加速此特定查询,并且会花费您在INSERT,UPDATE和DELETE上花费时间。

答案 1 :(得分:2)

警告:索引会加快检索时间,但会导致插入和更新运行得更慢。

答案 2 :(得分:2)

要回答索引每个字段的含义,只要通过插入,更新或删除修改了索引的数据,就会在使用索引时遇到性能损失。这是因为SQL需要维护索引。这是数据读取频率与修改频率之间的平衡。

在此特定查询中,唯一可能有帮助的索引将出现在您的JOIN子句中,字段为roots.idroot_words.root_id

由于领先WHERE,您的'%'子句中的所有检查均无法编入索引。这会导致SQL扫描这些表中的每一行以获得匹配值。

如果您能够删除前导'%',那么您将从这些字段的索引中受益...如果没有,您应该考虑实施full-text search;但要注意,这不是微不足道的。

答案 3 :(得分:1)

LIKE '%something%'一起使用时,索引无效。

这就像在字典中查找某些地方有ae的单词。字典(或本例中的索引)是根据单词的第一个字母,然后是第二个字母等组织的。它没有机制将ae中的所有单词放在一起。你最后还是从头到尾阅读整本字典。


索引CASE子句中使用的字段可能对您没有帮助。索引有助于在表格中轻松查找记录。 CASE子句是关于处理您找到的记录,而不是首先找到它们。


优化工具也可能难以优化多个不相关的OR条件,例如您的条件。优化器正在尝试缩小完成查询的工作量,但是当不相关的条件可以使记录可以接受时,这很难做到。


总而言之,您的查询将受益于roots(root_id)和/或roots(id)上的索引,但其他内容并不多。

如果您要索引其他字段,则两个主要成本是:
- 由于要写入的附加索引,增加了写入时间(插入,更新或删除) - 磁盘占用的空间增加