为什么“WHERE col LIKE'a%'”使用索引,而不是“WHERE col LIKE'%a%'”?

时间:2013-03-07 21:30:43

标签: mysql sql indexing

我刚发现这篇文章:

MySQL like query runs extremly slow for 5000 records table

我有兴趣了解asaph的帖子,他说:

  

我不希望select *来自客户的代码如'%a%'   快,因为它不可能使用索引。每条记录都必须如此   检查。考虑从客户那里选择*,其中代码如'a%'if   可能因为那可能会使用索引。

有人可以解释两个select语句之间的区别吗?我知道一个只有一个通配符,只能找到以“a”开头的东西。但为什么要将其编入索引?

3 个答案:

答案 0 :(得分:5)

虽然MySQL的B-tree索引的actual details比这更复杂,但是对于大多数目的而言,它足够接近于说在列上有索引可以让MySQL引擎执行SELECT位于您的桌面上,就好像该列已订购一样。

如果code列上有索引,并且您正在搜索code LIKE 'a%'所有的记录,那么所有MySQL(或其他任何SQL包,只要它' s足够聪明)必须做的是从一开始就吐出所有记录。到了' b'的开头。但是,如果您正在搜索code LIKE '%a%'的记录,那么已经按code排序的表不会帮助您,因为一行是否与WHERE子句匹配没有简单的关系到它在索引中的位置。因此,对于第二个查询,除了检查表中每一行的code条目的每个字符外,数据库无法合理地执行任何操作(除非它已经缓存了结果)。

直观地说这很容易理解,因为你可以想象自己做一个像人一样合理的事情。如果你想找到牛津英语词典中以' a'开头的所有单词,那么你只需要从一开始就查看所有页面的' a'在' b'的开头,你看到的所有内容都以' a'开头。如果你想找到字典中的所有单词,其中包含' a'在任何地方,然后订购的字典并没有为你提供很多帮助。如果你足够复杂,你可以合理地利用词典的顺序一点(例如通过使用你的知识,在第一个词之前的所有单词' b ...& #39;字典中的单词包含' a'),但最终你几乎要查看每个单词。

答案 1 :(得分:3)

来自manual

  

大多数MySQL索引(PRIMARY KEYUNIQUEINDEXFULLTEXT)都存储在B树中。 B树索引可用于使用=>>=<<=或{{1的表达式中的列比较运算符。以下BETWEEN语句不使用索引:

SELECT
     

如果SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%'; 的参数是不以通配符开头的常量字符串,则索引也可用于LIKE比较。例如,以下LIKE语句使用索引:

SELECT

答案 2 :(得分:2)

MySQL使用BTREE索引。

如果使用LIKE和前导通配符进行字符串比较,那么MySQL进行表扫描的速度会更快,因为索引不能用于缩小结果范围。

如果使用LIKE和尾随通配符进行字符串比较,则使用索引的速度会更快,因为需要扫描的记录更少。