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

Posted

技术标签:

【中文标题】是否可以索引此 mysql 查询中的所有字段?【英文标题】:Is it OK to index all the fields in this mysql query? 【发布时间】:2011-12-24 17:20:18 【问题描述】:

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

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

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

谢谢!

【问题讨论】:

【参考方案1】:

    您在表中索引列,而不是查询。

    您指定的搜索条件都不能使用索引(因为搜索词以通配符开头)。

    您应该确保 id 列已编入索引,以加快 JOIN 的速度。 (据推测,它已经在一个表中作为 PRIMARY KEY 索引,在另一个表中作为 FOREIGN KEY 索引)。

为了加快查询速度,您需要使用全文搜索。添加索引不会加速这个特定的查询,并且会花费您在 INSERT、UPDATE 和 DELETE 上的时间。

【讨论】:

【参考方案2】:

LIKE '%something%' 结合使用时,索引将无济于事。

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

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

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

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

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

【讨论】:

【参考方案3】:

要回答为每个字段编制索引的含义,只要通过插入、更新或删除来修改已编制索引的数据,使用索引就会对性能造成影响。这是因为 SQL 需要维护索引。这是读取数据的频率与修改数据的频率之间的平衡。

在这个特定查询中,唯一可能有帮助的索引是您的 JOIN 子句中的 roots.idroot_words.root_id 字段。

WHERE 子句中的所有检查都不能被索引,因为前导 '%'。这会导致 SQL 扫描这些表中的每一行以查找匹配值。

如果您能够删除前导 '%',那么您将受益于这些字段的索引...如果没有,您应该考虑实现 full-text search;但请注意,这并非小事。

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于是否可以索引此 mysql 查询中的所有字段?的主要内容,如果未能解决你的问题,请参考以下文章

mysql索引研究

Mysql中的联合索引前缀索引覆盖索引

如果我对非索引字段进行查询,是不是使用全表扫描

MySQL联合索引生效的条件、索引失效的条件

MySQL索引介绍

如何查看MySQL执行计划