是否可以索引此 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.id
和 root_words.root_id
字段。
WHERE
子句中的所有检查都不能被索引,因为前导 '%'
。这会导致 SQL 扫描这些表中的每一行以查找匹配值。
如果您能够删除前导 '%'
,那么您将受益于这些字段的索引...如果没有,您应该考虑实现 full-text search;但请注意,这并非小事。
【讨论】:
【参考方案4】:警告:索引会加快检索时间,但会导致插入和更新运行速度变慢。
【讨论】:
以上是关于是否可以索引此 mysql 查询中的所有字段?的主要内容,如果未能解决你的问题,请参考以下文章