我有这个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
另外,如何进一步提高上述查询的速度?
谢谢!
答案 0 :(得分:5)
您索引表中的列,而不是查询。
您指定的所有搜索条件都不能使用索引(因为搜索字词以外卡开头)。
您应确保将id
列编入索引,以加快JOIN
的速度。 (据推测,它已经在一个表中被索引为PRIMARY KEY而在另一个表中已被索引为外键)。
要加快此查询速度,您需要使用全文搜索。添加索引不会加速此特定查询,并且会花费您在INSERT,UPDATE和DELETE上花费时间。
答案 1 :(得分:2)
警告:索引会加快检索时间,但会导致插入和更新运行得更慢。
答案 2 :(得分:2)
要回答索引每个字段的含义,只要通过插入,更新或删除修改了索引的数据,就会在使用索引时遇到性能损失。这是因为SQL需要维护索引。这是数据读取频率与修改频率之间的平衡。
在此特定查询中,唯一可能有帮助的索引将出现在您的JOIN
子句中,字段为roots.id
和root_words.root_id
。
由于领先WHERE
,您的'%'
子句中的所有检查均无法编入索引。这会导致SQL扫描这些表中的每一行以获得匹配值。
如果您能够删除前导'%'
,那么您将从这些字段的索引中受益...如果没有,您应该考虑实施full-text search;但要注意,这不是微不足道的。
答案 3 :(得分:1)
与LIKE '%something%'
一起使用时,索引无效。
这就像在字典中查找某些地方有ae
的单词。字典(或本例中的索引)是根据单词的第一个字母,然后是第二个字母等组织的。它没有机制将ae
中的所有单词放在一起。你最后还是从头到尾阅读整本字典。
索引CASE子句中使用的字段可能对您没有帮助。索引有助于在表格中轻松查找记录。 CASE子句是关于处理您找到的记录,而不是首先找到它们。
优化工具也可能难以优化多个不相关的OR
条件,例如您的条件。优化器正在尝试缩小完成查询的工作量,但是当不相关的条件可以使记录可以接受时,这很难做到。
总而言之,您的查询将受益于roots(root_id)
和/或roots(id)
上的索引,但其他内容并不多。
如果您要索引其他字段,则两个主要成本是:
- 由于要写入的附加索引,增加了写入时间(插入,更新或删除)
- 磁盘占用的空间增加