首页/数据/SQL 速查/列上做运算导致索引失效
性能与执行计划72 条

列上做运算导致索引失效

WHERE 里对索引列做函数或运算时,B 树无法定位范围:改写成对常量做运算,或使用函数索引。

SQL 速查数据更新于 2026-10-12

示例

示例
-- 原写法:列上做 YEAR() 运算,索引失效
SELECT * FROM orders WHERE YEAR(created_at) = 2024;

-- 改写为范围条件,可走 idx_created
SELECT * FROM orders
WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';

-- MySQL 8.0.13+ 也可建函数索引(表达式需要括号包裹)
ALTER TABLE orders ADD INDEX idx_year ((YEAR(created_at)));

-- PostgreSQL 表达式索引
CREATE INDEX idx_orders_year ON orders ((EXTRACT(YEAR FROM created_at)));
原则保持索引列“裸用”:把运算移到常量一侧
函数索引MySQL 8.0.13+ 与 PG 均支持表达式索引;查询表达式必须与索引表达式一致
常见场景日期函数、字符串大小写、JSON 提取、CAST 转换

易错点

  • 把 DATE(created_at) = '2024-01-01' 当高效写法:改写为当天范围更通用,兼容所有版本
  • 建了函数索引却仍写原条件:表达式要完全一致才命中,用 EXPLAIN 验证

数据来源与参考

  • MySQL 8.0 Reference Manual · Functional Indexes
  • PostgreSQL Documentation §11.7 Indexes on Expressions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌