致命索引失效:索引列运算与函数索引不匹配

一、前言

除了类型转换,另一类高频索引失效问题:对普通索引列做函数、算术运算 ,以及表达式索引使用不规范。

很多开发者为了适配业务查询,习惯在 WHERE 条件中对索引列加工处理,直接导致精心建立的索引彻底作废,是线上慢查询的主要元凶之一。

二、核心开发规范

  1. 普通索引列,禁止在查询条件中进行任何计算、函数包裹;

  2. 表达式(函数)索引,查询表达式必须与建索引表达式完全一致,写法不同则无法命中。

三、底层原理通俗讲解

  • 普通B+树索引 :仅存储字段原始值,数据库无法对加工后的值匹配索引,一旦索引列参与运算,只能全表扫描;

  • 表达式索引:存储的是「函数/运算后的结果值」,仅能匹配完全相同的表达式,细微写法差异都会导致索引失效。

四、实战错误案例&优化方案

场景1:普通索引列使用函数(最高频错误)

表设计:bill 表 create_time 为 datetime 类型,建有普通单列索引。

❌ 错误写法(索引列套函数,索引失效)

sql 复制代码
SELECT * FROM bill WHERE DATE(create_time) = '2026-09-10';

✅ 正确优化写法(计算转移到常量侧,保留索引列原生形态)

sql 复制代码
SELECT * FROM bill WHERE create_time >= '2026-09-10 00:00:00' AND create_time < '2026-09-11 00:00:00';

场景2:普通索引列做算术运算

表设计:bill 表 amount 建有普通索引。

❌ 错误写法(索引列参与运算)

sql 复制代码
SELECT * FROM bill WHERE amount + 100 = 2000;

✅ 正确写法(常量侧运算,索引列无加工)

sql 复制代码
SELECT * FROM bill WHERE amount = 1900;

场景3:表达式索引写法不匹配,无法命中

第一步:创建表达式索引

sql 复制代码
CREATE INDEX idx_expr_bill_date ON bill ((DATE(create_time)));

✅ 正确写法(表达式完全一致,正常命中索引)

sql 复制代码
SELECT * FROM bill WHERE DATE(create_time) = '2026-09-10';

❌ 错误写法(函数写法变更,索引失效)

sql 复制代码
SELECT * FROM bill WHERE CAST(create_time AS DATE) = '2026-09-10';

关键结论 :函数索引对写法完全敏感,函数名、参数、顺序必须和建索引语句一模一样。

五、绝对禁止的写法汇总

  • 索引列 + 函数:DATE(col)、SUBSTR(col)、UPPER(col)

  • 索引列 + 算术运算:col+N、col-N、col*N、col/N

  • 表达式索引,查询表达式与建索引表达式不一致

六、最终评审口诀(记住不踩坑)

普通索引列不动,计算全放常量中;

函数索引严匹配,写法错乱索引空。

七、总结

索引失效绝大多数不是索引没建对,而是SQL写法不规范。开发和评审时,只要守住「类型一致、索引列不运算、函数索引严匹配」三条底线,就能规避99%的线上索引失效、慢查询性能问题。

相关推荐
码事漫谈13 小时前
黄仁勋被裁第一天,就收到了橄榄枝
后端
星恒随风13 小时前
MySQL 从零入门(五):MySQL 内置函数详解——日期、字符串、数学函数与实战案例
linux·数据库·笔记·sql·mysql
金銀銅鐵13 小时前
带您看懂字节码指令(二):空循环里有什么
java·后端·ai编程
皮皮林55115 小时前
比 Xshell 还好用的 SSH 客户端神器,MobaXterm 太爱了!
后端
吴名氏.15 小时前
Java转AI Agent教程(第十三周)混合检索与重排
java·数据库·人工智能·ai·ai agent
爱码少年15 小时前
Springboot下如何将CSV文件数据导入H2、Mysql数据库表
数据库·mysql·csv
我不会起名字32216 小时前
会话缓存失效排查:区分 Redis 失效与节点广播
redis·后端·go·即时通讯·im·故障排查
可乐ea16 小时前
智能体记忆该拆成几层:笔记、记忆表示与注入上下文
服务器·数据库·笔记·ai智能体·提示词工程·上下文工程·记忆系统
深入云栈17 小时前
Netty 4.2.x 源码深度解析 (二十三):ByteBuf 核心设计 —— 索引、类型与零拷贝
java·后端·架构
JackJiang17 小时前
IM踩坑:聊天消息ID怎么设计?一个UUID搞不定,我用双ID解决
后端·架构