不能,DATE_FORMAT() 是非确定性函数,MySQL 8.0 禁止为其创建函数索引;正确做法是添加 STORED 虚拟列并建索引,或改用范围查询(如 create_time >= '2026-04-01' AND create_time < '2026-05-01')。

MySQL 8.0 函数索引能加速 DATE_FORMAT() 查询吗?不能
直接在 WHERE 里写 DATE_FORMAT(create_time, '%Y%m') = '202604',哪怕你给 create_time 建了普通索引,也完全走不了索引——函数作用于字段,优化器无法下推条件。
更关键的是:DATE_FORMAT() 是非确定性函数(受 lc_time_names 等会话变量影响),MySQL 8.0 明确禁止用它建函数索引。执行 CREATE INDEX idx ON t ((DATE_FORMAT(create_time, '%Y%m'))) 会直接报错。
替代思路只有两个:
- 把格式化逻辑提前固化:加虚拟列
ym VARCHAR(6) GENERATED ALWAYS AS (DATE_FORMAT(create_time, '%Y%m')) STORED,再对它建普通索引 - 彻底放弃字符串格式化过滤,改用范围查询:比如查 2026 年 4 月,写成
create_time >= '2026-04-01' AND create_time
哪些日期函数能用于 MySQL 8.0 函数索引?
必须同时满足:确定性 + 无副作用 + 可比较 + 不含子查询/用户变量。常用且安全的有:
-
DATE():提取日期部分,CREATE INDEX idx_date ON t ((DATE(created_at)))合法 -
YEAR()、MONTH()、DAY():但注意,YEAR(created_at)索引只对WHERE YEAR(created_at) = 2026生效,对WHERE created_at >= '2026-01-01'无效 -
DATE_SUB()、DATE_ADD():可用于构造偏移表达式,例如(DATE_SUB(created_at, INTERVAL DAYOFWEEK(created_at)-1 DAY))表示周一,但需确认所有子函数都确定
绝对不能用的: NOW()、CURDATE()、SYSDATE()、RAND()、UUID() —— 它们建索引会直接失败。
函数索引生效的硬性前提:WHERE 条件必须字面量匹配
你建了 CREATE INDEX idx_created_date ON orders ((DATE(created_at))),那只有下面这种查询能走索引:
SELECT * FROM orders WHERE DATE(created_at) = '2026-04-12';
以下全都不行:
-
WHERE created_at >= '2026-04-12' AND created_at < '2026-04-13'(没调用函数,但和索引表达式不一致) -
WHERE DATE(created_at) > '2026-04-10'(函数索引只支持等值或部分范围,且依赖优化器是否识别) -
WHERE DATE(created_at) = DATE('2026-04-12')(右边也套了函数,表达式不完全相同)
也就是说:函数索引不是“让函数变快”,而是“让这个特定函数调用能命中索引”。它不改变底层字段的可索引性,也不提升其他写法的性能。
比函数索引更稳、更快的日期查询写法
绝大多数日期过滤场景,根本不需要函数索引。直接用标准范围写法,配合基础索引,性能和可维护性都更好:
- 查某天:
created_at >= '2026-04-12' AND created_at < '2026-04-13' - 查某月:
created_at >= '2026-04-01' AND created_at < '2026-05-01' - 查最近 N 天:
created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) - 查本周一到周日:
created_at >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AND created_at < DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
这些写法全部能走 created_at 的 B-tree 索引,且不受会话变量、字符集、函数确定性限制。真正容易被忽略的点是:右边界务必用开区间(<),而不是 <= 或 BETWEEN,否则容易漏掉毫秒级数据或触发隐式类型转换。


















