为啥 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 INDEXFORCE 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`) 时会删除我的索引的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 MySQL CREATE TABLE 语句失败?

mysql 里 date的长度 为啥总是为0

如何在 MySQL 列中保存 DATE

mysql数据库里只有一条数据为啥查询出来有两条重复的数据

我:正在尝试使用 STR_TO_DATE 但为啥返回 null?

如何在MYSQL中联合多个表[重复]