我刚发现这篇文章:
MySQL like query runs extremly slow for 5000 records table
我有兴趣了解asaph的帖子,他说:
我不希望select *来自客户的代码如'%a%' 快,因为它不可能使用索引。每条记录都必须如此 检查。考虑从客户那里选择*,其中代码如'a%'if 可能因为那可能会使用索引。
有人可以解释两个select语句之间的区别吗?我知道一个只有一个通配符,只能找到以“a”开头的东西。但为什么要将其编入索引?
答案 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 KEY
,UNIQUE
,INDEX
和FULLTEXT
)都存储在B树中。 B树索引可用于使用=
,>
,>=
,<
,<=
或{{1的表达式中的列比较运算符。以下BETWEEN
语句不使用索引:SELECT
如果
SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
的参数是不以通配符开头的常量字符串,则索引也可用于LIKE
比较。例如,以下LIKE
语句使用索引:SELECT
答案 2 :(得分:2)
MySQL使用BTREE索引。
如果使用LIKE和前导通配符进行字符串比较,那么MySQL进行表扫描的速度会更快,因为索引不能用于缩小结果范围。
如果使用LIKE和尾随通配符进行字符串比较,则使用索引的速度会更快,因为需要扫描的记录更少。