2011-11-08 61 views
4

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

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 

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

谢谢!

回答

5
  1. 您在表中索引列而不是查询。

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

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

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

2

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

2

要回答为每个字段建立索引的含义,每当通过插入,更新或删除修改索引的数据时使用索引时都会出现性能问题。这是因为SQL需要维护索引。这是数据读取频率与修改频率的平衡。

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

您的WHERE子句中的任何支票都没有索引,因为前导'%'。这会导致SQL扫描这些表中的每一行以获取匹配的值。

如果你能够删除领先的'%',那么你将受益于这些领域的索引......如果不是,你应该考虑实施full-text search;但要警告,这不是微不足道的。

1

当与LIKE '%something%'一起使用时,索引将无济于事。

这就像在字典中查找字词的地方有ae。字典(或本例中的Index)是基于单词的第一个字母,然后是第二个字母等进行组织的。它没有任何机制将所有与ae相关的单词放在一起。你仍然会从头到尾阅读整本字典。


索引CASE子句中使用可能不会帮助你的领域。通过在表格中查找记录很容易,索引帮助您。 CASE条款是关于处理您找到的记录,而不是首先找到它们。


优化器也可以与优化多个无关OR条件如你的纠缠。优化器试图缩小完成查询的工作量,但当无关的条件可以使记录可以接受时,很难做到这一点。


总而言之您的查询就会从索引中受益的roots(root_id)和/或roots(id),但仅此而已。

如果你要索引附加字段虽然,两个主要的成本是:
- 增加写入时间(插入,更新或删除),由于额外的指标写入
- 磁盘

上占据上升空间