MySQL 索引失效 20 例

适用 MySQL5.7/8.0 ,默认表:t_user(id PK,uid INT,name VARCHAR(32),phone VARCHAR(11),create_time DATETIME,status TINYINT) 索引: PRIMARY(id)、idx_phone(phone)、idx_name_status(name,status)、idx_ct(create_time)

一、索引列使用函数 / 运算(5 例:1~5)

例 1:索引字段做数学运算

sql

sql 复制代码
-- 失效SQL
SELECT * FROM t_user WHERE id+1=100;
-- 原因:索引列参与算术运算,B+树无法匹配
-- 优化
SELECT * FROM t_user WHERE id=99;

例 2:索引字段套 YEAR () 日期函数

sql

sql 复制代码
--失效
SELECT * FROM t_user WHERE YEAR(create_time)=2025;
--优化1(区间,通用)
SELECT * FROM t_user WHERE create_time>='2025-01-01' AND create_time<'2026-01-01';
--优化2 MySQL8.0:函数索引 CREATE INDEX idx_year_ct ON t_user((YEAR(create_time)));

例 3:LEFT/RIGHT 截取字符串

sql

sql 复制代码
--失效
SELECT * FROM t_user WHERE LEFT(phone,3)='138';
--优化
SELECT * FROM t_user WHERE phone LIKE '138%';

例 4:TRIM 去除空格函数

sql

sql 复制代码
--失效
SELECT * FROM t_user WHERE TRIM(phone)='13800138000';
--优化:入库去空格,查询直接等值
SELECT * FROM t_user WHERE phone='13800138000';

例 5:DATE_FORMAT 格式化索引时间

sql

sql 复制代码
--失效
SELECT * FROM t_user WHERE DATE_FORMAT(create_time,'%Y-%m-%d')='2025-05-01';
--优化
SELECT * FROM t_user WHERE create_time>='2025-05-01' AND create_time<'2025-05-02';

二、隐式类型转换(4 例:6~9,高频踩坑)

例 6:字符串索引字段传入数字(phone 是 varchar)

sql

sql 复制代码
--失效:字符串=数字,MySQL隐形转字段为数值
SELECT * FROM t_user WHERE phone=13800138000;
--优化:常量加引号
SELECT * FROM t_user WHERE phone='13800138000';

例 7:int 字段用字符串常量查询

sql

sql 复制代码
--uid int,失效
SELECT * FROM t_user WHERE uid='123abc';
--优化
SELECT * FROM t_user WHERE uid=123;

例 8:JOIN 两边字段类型不一致(user.id int,order.uid varchar)

sql

sql 复制代码
--失效,关联字段类型不一致隐转
SELECT * FROM t_user u JOIN t_order o ON u.id=o.uid;
--优化:统一字段数据类型
alter table t_order modify uid int not null;

例 9:ENUM 与字符串对比隐式转换

sql

sql 复制代码
--status枚举,查询传字符串触发转换
SELECT * FROM t_user WHERE status='1';
--优化:使用定义枚举数值
SELECT * FROM t_user WHERE status=1;

三、条件符号 & 关键字导致失效(6 例:10~15)

例 10:!=、<> 不等于

sql

sql 复制代码
--失效
SELECT * FROM t_user WHERE status<>1;
--优化:拆分业务,用正向枚举筛选,status in(0,2)
SELECT * FROM t_user WHERE status IN(0,2);

例 11:NOT IN 非包含查询

sql

sql 复制代码
--失效
SELECT * FROM t_user WHERE uid NOT IN(1001,1002);
--优化:业务拆分,改用LEFT JOIN过滤空值

例 12:IS NOT NULL 非空判断

sql

sql 复制代码
--phone有索引,IS NOT NULL不走索引
SELECT * FROM t_user WHERE phone IS NOT NULL;
--优化:设计字段NOT NULL+默认空串,查询phone<>''

例 13:OR 左右单侧无索引(name 有索引,status 无)

sql

sql 复制代码
--失效:OR一端无索引整句全表扫
SELECT * FROM t_user WHERE name='张三' OR status=1;
--优化:UNION ALL拆分两条SQL
SELECT * FROM t_user WHERE name='张三'
UNION ALL
SELECT * FROM t_user WHERE status=1;

例 14:NOT LIKE 前置通配符 % xxx

sql

sql 复制代码
--失效:前缀%无法走B+树索引
SELECT * FROM t_user WHERE phone LIKE '%1380';
--优化:倒序字段+反向索引,或ES检索

例 15:前后双 % 通配符 %%

sql

sql 复制代码
--全失效
SELECT * FROM t_user WHERE name LIKE '%三%';
--优化:全文索引FULLTEXT/Elasticsearch

四、联合索引违反最左前缀(3 例:16~18,联合索引 idx_name_status (name,status))

例 16:跳过首字段,直接用第二列查询

sql

sql 复制代码
--失效,缺最左name
SELECT * FROM t_user WHERE status=1;
--优化:补全最左前缀,或单独给status建索引
SELECT * FROM t_user WHERE name!='' AND status=1;

例 17:最左字段做范围查询,后置字段索引失效

sql

sql 复制代码
--name范围>,后面status无法使用索引
SELECT * FROM t_user WHERE name>'张三' AND status=1;
--优化:调整索引顺序(status,name),等值在前范围在后
CREATE INDEX idx_status_name(status,name);

例 18:字段颠倒查询顺序,无最左

sql

sql 复制代码
--失效:先status后name,和索引顺序不一致
SELECT * FROM t_user WHERE status=1 AND name='李四';
--优化:条件顺序不影响优化器,索引顺序不动,无需改SQL,建索引规范即可

五、其他特殊失效场景(2 例:19~20)

例 19:索引选择性过低(字段区分度极差)

sql

sql 复制代码
--status只有0/1两种值,选择性<20%,优化器放弃索引全表扫
SELECT * FROM t_user WHERE status=1;
--优化:小数据无视;大数据按业务分区,不建单字段索引

例 20:MySQL 优化器评估代价后放弃索引(数据量占比过大)

sql

sql 复制代码
--符合条件数据超全表30%,优化器判定全表更快,放弃索引
SELECT * FROM t_user WHERE create_time>'2020-01-01';
--优化:FORCE INDEX强制走索引,或分表归档历史数据
SELECT * FROM t_user FORCE INDEX(idx_ct) WHERE create_time>'2020-01-01';

精简背诵口诀

函数运算隐转换,百分前缀 OR 半边; 不等空值 notin,最左丢了索引残; 选择性低数据多,优化弃索全表翻。

相关推荐
蓝天下的守望者6 分钟前
svt_apb_if里的宏定义问题
运维·服务器·数据库
上海云盾-小余17 分钟前
网站频繁遭遇 SQL 注入溯源与原生漏洞修复全流程总结
数据库·sql
数据库小学妹18 分钟前
国家区域医疗中心国产化改造实战:数据库选型、跨院区数据互通与踩坑经验
数据库·国产数据库·数据库选型·医疗信息化·信创数据库·医疗信创
TPBoreas1 小时前
MySQL性能优化面试全攻略
mysql·面试·性能优化
xlq223221 小时前
11.表的内外连接,索引
mysql
AllData公司负责人2 小时前
数据库同步平台|AIIData数据中台实现OceanBase、达梦数据库、OpenGauss、人大金仓、Hive、TDengine 一键接入Doris
大数据·数据库·hive·mysql·oceanbase·tdengine
2603_954708312 小时前
全维度容错设计,打造微电网安全运行屏障
服务器·网络·数据库·人工智能·分布式·安全
IvorySQL2 小时前
从双解析器到循环工程:IvorySQL 五年技术演进路线的深度观察
大数据·数据库·人工智能·postgresql·开源
wefg13 小时前
【MySQL】事务
数据库·mysql
黑白极客3 小时前
mysql的高可用性
数据库·mysql