为啥 MySQL 在使用 DATE(`table`.`column`) 时会删除我的索引
Posted
技术标签:
【中文标题】为啥 MySQL 在使用 DATE(`table`.`column`) 时会删除我的索引【英文标题】:Why does MySQL drops my index when using DATE(`table`.`column`)为什么 MySQL 在使用 DATE(`table`.`column`) 时会删除我的索引 【发布时间】:2014-08-07 08:27:32 【问题描述】:我有一个包含几列的 mysql innodb 表。
其中一个被命名为“dateCreated”,它是一个DATETIME
列,并且已被索引。
我的查询:
SELECT
*
FROM
`table1`
WHERE
DATE(`dateCreated`) BETWEEN '2014-8-7' AND '2013-8-7'
MySQL 出于某种原因拒绝使用dateCreated
列上的索引(即使使用USE INDEX
或FORCE INDEX
。
但是,如果我将查询更改为:
SELECT
*
FROM
`table1`
WHERE
`dateCreated` BETWEEN '2014-8-7' AND '2013-8-7'
注意DATE(...)
删除
MySQL 使用索引很好。 我可以不使用 DATE() 函数来管理,但这对我来说很奇怪。
我知道 MySQL 可能会索引完整的日期和时间,当只搜索其中的一部分时,它会变得混乱或其他什么。但是必须有一种方法可以使用部分日期(比如说MONTH(...)
或DATE(...)
),并且仍然可以从索引列中受益并避免全表扫描。
有什么想法吗?
谢谢。
【问题讨论】:
MySQL 不能对这样的表达式使用索引。因此,请注意仅在比较运算符的右侧使用函数。 看看***.com/questions/10595037/… 【参考方案1】:正如您所观察到的,一旦将函数应用于该字段,您就会破坏对索引的访问。所以,
如果不使用 between 会有帮助。 将函数应用于数据的基本原理是,您可以获得与参数匹配的数据。只有2个参数日期和几百个?千?百万?行数据。为什么不反转这个,改变参数以适应数据? (使它成为一个“sargable”谓词)
SELECT
*
FROM
`table1`
WHERE
( `dateCreated` >= '2013-08-07' AND `dateCreated` < '2014-08-07' )
;
Note 2013-08-07 首先使用,如果还使用 between,则必须为 true。如果第一个日期小于第二个日期,则使用 between 不会得到任何结果。
另请注意,正好包含 12 个月的数据 >= '2013-08-07' AND 李>
使用 date(dateCreated
) 和 between 的组合将包含 1 天,因为将包含“2014-08-07”期间的所有事件。如果您故意想要一年零 1 天,则将 1 天添加到较高的日期,即
【讨论】:
以上是关于为啥 MySQL 在使用 DATE(`table`.`column`) 时会删除我的索引的主要内容,如果未能解决你的问题,请参考以下文章