带有索引的 mysql 日期时间字段获得范围 'like' 与 'between and' 性能

标签 mysql datetime sql-like between

我发现 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'在查询日期时间字段时不能使用索引,因为mysql应该先将日期时间字段转换为字符串并将字符串发送给like命令。 这是正确的吗?

最佳答案

假设t.active_time的类型是 DATETIME ,

由于函数调用,以下查询不能使用索引。全部active_time必须即时转换为 DATE'2013-06-30' 比较前的值.此字符串转换为 DATE value 放在首位,这只在查询开始时发生一次。

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''2007-12-01'被转换到DATETIME在这种情况下,因为 <>运营商允许这样做。

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' .

关于带有索引的 mysql 日期时间字段获得范围 'like' 与 'between and' 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17101436/

相关文章:

php - 我该如何让我的 friend 的 friend 使用 mysql 和 PHP

php - 语法错误或访问冲突 : 1055 Expression #17 in group by

mysql - SQL WHERE 字符串 LIKE 字段

MYSQL:对具有特定值的行求和

php - 如何调试 MySQL 语法错误#1064?

sql-server - T-SQL : How to update just date part of datetime field?

ruby - Ruby 中的 DateTime.parse() 是否依赖于语言环境?

ruby - 如何将 apache 日志时间转换为 activerecord :datetime

delphi - 如何使用 like 子句和元音变音来过滤数据集中的字符串字段?

php - 带 % 通配符的 Mysqli 准备语句