【问题标题】:Mysql - Query DATETIME field (indexed) performanceMysql - 查询 DATETIME 字段(索引)性能
【发布时间】:2016-05-24 09:36:08
【问题描述】:

在我的数据库中,有一个名为Profile 的表,其中有一个名为DATETIME 的字段birthday。

我想查询生日在 05-24 和 06-07 (mm-dd) 之间的所有记录,无论是哪一年,我使用以下查询:

DATE_FORMAT(`Profile`.`birthday`, "%m-%d") >= '05-24' 
AND DATE_FORMAT(`Profile`.`birthday`, "%m-%d") <  '06-07'

问题是这样做,birthday列的index有没有用,查询太慢,我想提高我的速度查询

请告诉我是否有任何解决方法仍然可以完成这项工作并同时提高查询性能

【问题讨论】:

  • 您使用的是什么版本的 MySQL? 5.7 允许索引“虚拟列”
  • 我用的是 mysql 5.6,你可以给我看看另一个解决方案
  • 使用虚拟列是个好主意。使用虚拟持久性列,因此您也可以在其上使用索引

标签: php mysql datetime indexing


【解决方案1】:

是的,

原因是您在 WHERE 中的字段上使用了 FUNCTION。这意味着MySQL必须读取表的所有记录(FULL TABLE SCAN)。

您可以添加一个新字段birthday2,您可以在其中仅存储日期和月份以及标准化年份,例如

UPDATE yourTable set birthday2 = DATE_FORMAT(Profile.birthday, "%m-%d-0001");

十个你可以选择喜欢

SELECT * from yourTable
WHERE birthday2 BETWEEN ''05-24-0001' AND '06-07-001';

如果你在这个字段上设置一个索引,它将被使用

【讨论】:

  • 嗨@Bernd Buffen,我在两者之间使用时遇到问题。 使用索引条件解释(SELECT * from profiles WHEREbirthday2 BETWEEN '0001-01-01' AND '0001-03-06' )。但是说明(SELECT * from profiles WHEREbirthday2 BETWEEN '0001-01-01' AND '0001-06-06') 使用 where。
  • 有什么问题?
  • 这是我的屏幕图像。 link 和 link。如果您需要任何进一步的信息,请与我联系。谢谢!
【解决方案2】:

添加另一列

mmdd CHAR(5) CHARACTER SET ascii
and
INDEX(mmdd)

使用UPDATE 和SET mmdd = DATE_FORMAT(..., "%m-%d") 设置它

作为一个字符串 (CHAR),它会比较“正确”,除非您环绕年份边界(例如,11 月到 2 月)。

对于 5.6 - 明确执行。
对于 5.7 或 MariaDB -- 使用虚拟列。

请记住,如果您的日期范围“太大”(大约 2 个月),优化器将忽略索引并进行全表扫描。这是经过深思熟虑的,实际上是最佳的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多