为什么mysql在使用日期函数进行换行时命中索引
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么mysql在使用日期函数进行换行时命中索引相关的知识,希望对你有一定的参考价值。
IMO,当add_time字段用date()func换行时,下面的mysql不会命中索引,但是从解释结果来看,它命中索引,为什么?
explain
SELECT count(0)
FROM xxx
WHERE date(add_time) >= date_sub(curdate(), INTERVAL 7 day);
众所周知,EXPLAIN报告难以解释。他们将过多的信息过载到了几个领域。你可以试试
type: index
表示它正在进行索引扫描,这意味着它正在访问索引中的每个条目。
这会访问与表扫描相同数量的条目,除了它是针对辅助索引而不是聚簇(主)索引。
当我们看到type: index
时,EXPLAIN显示possible_keys: NULL
,这意味着它无法使用任何索引进行有效搜索。但它也显示了key: add_time
,这意味着它用于索引扫描的索引是add_time
。
索引扫描是由于MySQL无法自行优化表达式或函数调用。例如,如果您尝试搜索特定月份的日期,则可以搜索month(add_time) = 4
但不会在add_time上使用索引,因为该月份的日期分散在索引中,而不是全部组合在一起。
你可能知道date(add_time)
应该可以通过索引进行搜索,但是MySQL并没有做出推断。 MySQL只是看到你正在使用一个函数,它甚至没有尝试使用索引。
这就是为什么MySQL 5.7引入generated columns以允许我们索引表达式,而MySQL 8.0通过允许index to defined for an expression使其更好,而不需要我们首先定义生成的列。
我想你可能在这里误解了解释计划。如果你看下possible_keys
,你会发现它是NULL
。从MySQL documentation上解释输出格式:
如果此列为NULL(或在JSON格式的输出中未定义),则没有相关索引。
因此,Extra
部分中提到的正在使用的索引可能与add_time
无关。
以上是关于为什么mysql在使用日期函数进行换行时命中索引的主要内容,如果未能解决你的问题,请参考以下文章