15

我只是发现mysql可以使用如下查询日期时间:

like '2013-06-12%'

我认为它不能使用索引。我谷歌它,但不能直接找到这样的主题。因此,我使用具有 3308614 条记录的表进行了测试。第一个 SQL:

SELECT * FROM subscription t WHERE DATE(t.active_time) = '2013-06-30';

我们都知道这个 SQL 不能使用索引,它需要 4 秒才能得到结果。第二条 SQL:

SELECT * FROM subscription t WHERE t.active_time LIKE '2013-06-30%';

我不知道它是否可以使用索引,但它也需要 4 秒。第三条 SQL:

SELECT * FROM subscription t WHERE t.active_time > '2007-11-30' AND t.active_time < '2007-12-01';

我们所知道的第三条 SQL 可以使用索引,它需要 0.016 秒。

所以我认为'like'在查询datetime字段时不能使用索引,因为mysql应该先将datetime字段转换为字符串并将字符串发送给like命令。这个对吗 ?

4

2 回答 2

19

假设它t.active_time的类型是DATETIME,

由于函数调用,以下查询无法使用索引。在与 比较之前,必须将所有active_time内容即时转换为一个DATE'2013-06-30'。这个字符串首先被转换为一个DATE值,并且这只在查询的最开始发生一次。

SELECT * FROM subscription t WHERE DATE(t.active_time) = '2013-06-30';

出于类似原因,第二个查询也不能使用索引。您实际上是在进行字符串比较(由于LIKE运算符)。所有active_time值都即时转换为字符串。

SELECT * FROM subscription t WHERE t.active_time LIKE '2013-06-30%';

只有最后一个可以使用索引。在这种情况下,字符串'2007-11-30'and'2007-12-01'被强制转换为DATETIME,因为<and>运算符允许这样做。

SELECT * FROM subscription t WHERE t.active_time > '2007-11-30' AND t.active_time < '2007-12-01';

后者也适用于=BETWEEN运算符。

有关信息,所有类型都可以与字符串进行比较LIKE运算符与字符串进行比较,但由于需要隐式转换,因此会遇到与上述相同的问题。

t.active_time = '2013-06-30'不能按预期工作,因为'2013-06-30'被强制转换为一个DATETIME值,也就是说'2013-06-30 00:00:00'.

于 2013-06-14T06:44:17.533 回答
5

这种情况的一种替代方法是执行以下操作:

SELECT *
FROM subscription t
WHERE t.active_time BETWEEN '2013-06-30 00:00:00' AND '2013-06-30 23:59:59';

最后你会得到那天的所有事件。

于 2014-02-14T22:10:46.920 回答