为什么SQL“像'模式%'这样的列”不使用索引?

时间:2019-11-15 20:33:09

标签: mysql

尝试了3种不同的方式。

第一

explain select * from test where create_time like '2019-10%';
id|select_type|table|partitions|type|possible_keys       |key|key_len|ref|rows |filtered|Extra      |
--|-----------|-----|----------|----|--------------------|---|-------|---|-----|--------|-----------|
 1|SIMPLE     |test |          |ALL |test_create_time_IDX|   |       |   |10376|   11.11|Using where|

第二

explain select * from test where create_time between '2019-10-01 00:00:00' and '2019-10-31 23:59:59';
id|select_type|table|partitions|type |possible_keys       |key                 |key_len|ref|rows|filtered|Extra                |
--|-----------|-----|----------|-----|--------------------|--------------------|-------|---|----|--------|---------------------|
 1|SIMPLE     |test |          |range|test_create_time_IDX|test_create_time_IDX|6      |   |   5|     100|Using index condition|

第三

explain select * from test where date_format(create_time,'%Y-%m') = '2019-10';
id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows |filtered|Extra      |
--|-----------|-----|----------|----|-------------|---|-------|---|-----|--------|-----------|
 1|SIMPLE     |test |          |ALL |             |   |       |   |10376|     100|Using where|

有人告诉我,“ like'pattern%'”将使用索引。“ like'%pattern%'”,“ like'%pattern'”不会。
但是在 1st 条件下,它没有按我的想法工作。是因为create_time的列类型为DATETIME吗?
而且在官方参考手册中与索引进行交互时,我找不到所有这些“相似” SQL的区别的详细信息。
有人可以和我分享官方链接吗?(我所得到的只是传闻证据)

1 个答案:

答案 0 :(得分:3)

考虑this part of the documentation

  

B树索引可用于使用=>>=<<=BETWEEN个运算符。如果LIKE的参数是一个不以通配符开头的常量字符串,则索引也可以用于LIKE比较。

旁注:作为documented here大多数MySQL索引(PRIMARY KEY,UNIQUE,INDEX和FULLTEXT)存储在B树中


在您的示例中:

create_time like '2019-10%'

您正在将日期与字符串进行比较。这需要MySQL转换数据。如您在explain的输出中所见,可以使用索引,但是它将是完整索引扫描。如果create_time是字符串,则索引将与范围扫描一起使用(效率更高)。

create_time between '2019-10-01 00:00:00' and '2019-10-31 23:59:59'

between允许MySQL优化索引的使用(范围扫描)。

date_format(create_time,'%Y-%m') = '2019-10''

一个功能开始起作用。索引将不被使用。