mysql - 为什么sql "column like '模式%'"不使用索引?

标签 mysql date query-optimization where-clause sql-like

<分区>

尝试了 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 的差异的详细信息。
谁能给我一个官方链接吗?(我得到的都是道听途说)

最佳答案

考虑 this part of the documentation :

A B-tree index can be used for column comparisons in expressions that use the =, >, >=, <, <=, or BETWEEN operators. The index also can be used for LIKE comparisons if the argument to LIKE is a constant string that does not start with a wildcard character.

旁注:如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''

一个函数开始发挥作用。索引不会被使用。

关于mysql - 为什么sql "column like '模式%'"不使用索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58884295/

相关文章:

php - MySQL 与 WHERE 进行重复更新?

mysql - 如何将sql日期格式unix时间戳转换为dd mm yy格式的日期格式?

mysql - 从一条记录中选择特定数量的记录

php - 即使代码成功完成,仍给出 500 内部服务器错误

mysql - JSON 字符串 - 在 MySQL 数据库中包含单引号

sql - Impala 中的 OVERLAPS 函数

python - 如何在 python 中创建日期间隔列表?

SQL:基于聚合函数过滤组

c# - Linq-to-SQL 和 sp_reset_connection

mysql - 在 PRIMARY KEY 上使用 JOIN 时应该使用什么索引