5个让索引失效的常见写法

  • 约1204字
  • 技术
  • 2026年3月27日

上周帮一个朋友排查问题,他的订单查询页面加载要12秒。查了代码,写得没问题啊,索引也建了,怎么还是慢?我让他把慢查询的EXPLAIN结果发给我一看——好家伙,索引根本没生效。

1. 最常见的坑:索引列上做了函数运算

很多人会这样写查询:

SELECT * FROM orders WHERE YEAR(created_at) = 2026;
SELECT * FROM users WHERE SUBSTRING(name, 1, 3) = '张';

这样索引列参与了运算,数据库只能用全表扫描。正确的做法是把运算移到右边:

SELECT * FROM orders WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01';

如果你真的需要对索引列做函数运算,考虑用函数索引(MySQL 8.0+)或表达式索引(PostgreSQL)。

2. 字符串类型不匹配

这是个容易被忽视的问题。

假设你有个user_id字段是varchar类型存的是数字,然后你这样查:

SELECT * FROM orders WHERE user_id = 12345;

注意12345是数字,数据库在做比较时会做隐式类型转换,把varchar转成数字。这个转换会导致索引失效。

正确写法:

SELECT * FROM orders WHERE user_id = '12345';

加引号,确保类型一致。

3. 联合索引顺序写反了

很多人知道建联合索引,但不知道顺序很重要。

假设有张用户表,查询条件是WHERE status = 'active' AND age > 18,你建了索引(age, status),那这个索引根本用不上——因为数据库是按从左到右的顺序匹配,你第一个条件是age,但查询第一个条件是status。

原则:把区分度高的列放前面, WHERE条件最频繁的列放前面

更好的做法是建两个索引:(status, age) 或 (status) + (age),看查询频率。

4. LIKE通配符开头的模糊匹配

SELECT * FROM products WHERE name LIKE '%手机%';

这种以%开头的模糊匹配,索引是无效的。只能走全表扫描。

如果你确实需要全文搜索,有两个替代方案:

  1. 用Elasticsearch等搜索引擎
  2. 如果是MySQL 5.7+,可以建generated column + 函数索引
ALTER TABLE products ADD COLUMN name_reverse VARCHAR(255) GENERATED ALWAYS AS (REVERSE(name));
CREATE INDEX idx_name_reverse ON products(name_reverse(10));

查询时:

SELECT * FROM products WHERE name_reverse LIKE REVERSE('%手机%');

5. 范围查询放在最后

联合索引中,如果某个列使用了范围查询(>、<、BETWEEN),那它右边的列就很难用到索引。

假设索引是 (status, created_at, user_id),查:

WHERE status = 'active' AND created_at > '2026-01-01' AND user_id = '123'

只有前两列能用到索引,user_id这列是走不了索引的。

如果可能,把范围查询放到最后,或者拆分查询。

怎么快速定位索引问题

上面5个是最常见的,但不是全部。我的建议是:

  1. 慢查询日志:打开MySQL的slow_query_log,把超过1秒的SQL都记录下来
  2. EXPLAIN分析:每个慢查询都跑一遍EXPLAIN,看type列是不是ALL(全表扫描)
  3. 索引统计信息:定期执行 ANALYZE TABLE,让数据库更新索引统计信息
-- MySQL查看查询执行计划
EXPLAIN SELECT * FROM orders WHERE user_id = '12345';

-- 更新统计信息
ANALYZE TABLE orders;

索引不是万能的,建了不一定用,用了不一定对。关键是要理解索引的原理,知道哪些操作会让它失效。

下次遇到查询慢,别急着改代码重构,先跑一遍EXPLAIN,看看索引是不是真的生效了。90%的性能问题,改改SQL写法就能解决。

相关文章

不花一分钱:在本地运行开源LLM

想在本地运行大语言模型但担心配置复杂或硬件要求过高?本文分享4款主流开源LLM本地部署工具,对比各自优缺点与适用场景,并给出具体的硬件配置建议,帮助开发者零成本搭建本地AI环境。

查看更多

接口文档还在手写?AI 3分钟搞定

接口文档同步是开发痛点,本文分享如何用AI工具3分钟自动生成并维护接口文档,包含具体工具、命令和避坑指南。

查看更多

为什么你的Prompt总是不好用?

本文通过一个真实的Prompt优化案例,分享从"完全无法使用"到"产出可用结果"的完整迭代过程,总结出3个关键调试技巧,帮助读者避免常见坑。

查看更多