他的回复:
加了索引但执行计划没走,先确认三件事:索引是不是真的建在查询用到的那一列上、优化器是不是认为全表扫描更便宜、以及 SQL 写法有没有让索引失效。 一,索引与实际条件列不匹配。where a = 1 and b > 2 建了 (b) 单列索引,优化器可能宁可全表扫。要看联合索引,且范围条件放最后。用 show index from 表 确认列顺序,别只看索引名。 二,选择性问题。如果该列区分度极低(比如状态列只有 0/1),优化器算出来走索引回表的成本高于全表顺序扫描,就会放弃索引。用 explain 的 rows 和 filtered 估计值判断,filtered 很低说明筛选性差。 三,SQL 写法导致失效。列上套函数、隐式类型转换、前导通配 like '%x'、or 连接的条件里有一侧无索引,都会让索引不可用。日期列被 date_format(create_time,'%Y-%m-%d')=... 包住是高频坑,改成范围比较。 四,统计信息过期。表数据变化大但没更新统计,优化器按旧的数据分布做决策。analyze table 表名 之后再看执行计划,很多"加了索引没反应"都是这一步解决的。 五,你是不是在看重放缓存。explain 看的是优化器计划,不是实际执行。真正的执行次数在 explain analyze(8.0 支持)或者慢日志里。有些情况计划选了索引,但实际因为回表太多中途放弃。 最后一条:确认索引不是被隐藏或不可见状态。8.0 可以用 alter table 表名 alter index 索引名 invisible 把索引隐藏,隐藏后优化器看不见但索引还在,用 show index 看 Visible 列是 YES 还是 NO。