不一定。查询慢的原因多样,索引缺失只是其一;即使有索引也可能因函数、类型转换、模糊匹配等失效;执行计划(如EXPLAIN ANALYZE)比单纯有无索引更关键;其他原因包括SELECT *、JOIN不当、统计信息过期、锁等待及硬件瓶颈等。

不一定。查询慢的原因很多,索引缺失只是常见原因之一,但不是唯一原因。
索引确实重要,但不是万能的
没有合适索引时,数据库可能走全表扫描,数据量大时自然变慢。但即使有索引,也可能不生效:比如查询条件用了函数(WHERE UPPER(name) = 'ABC')、隐式类型转换(WHERE user_id = '123',而 user_id 是整型)、或使用了不匹配的前缀(LIKE '%abc' 无法用到 B-tree 索引)。这时加了索引也白加。
执行计划比“有没有索引”更关键
真正要查的是数据库实际怎么执行的。用 EXPLAIN(MySQL/PostgreSQL)或 EXPLAIN ANALYZE 看执行计划,关注几件事:
- 是否走了预期的索引(key 字段是否非 NULL)
- 扫描行数(rows 或 estimated rows)是否远超结果集
- 有没有临时表(Using temporary)或文件排序(Using filesort)
- 连接顺序是否合理,小表是否驱动了大表
其他高频性能杀手
很多慢查询和索引完全无关:
- 大字段 SELECT *:查了不需要的 TEXT、BLOB 或长 VARCHAR,拖慢网络和内存
- 不合理的 JOIN 或子查询嵌套:尤其在没有 ON 条件或关联字段无索引时,容易产生笛卡尔积
- 统计信息过期:优化器基于旧的行数/分布估算执行计划,导致选错索引或连接方式
- 锁等待或高并发争用:比如 UPDATE 正在写某行,SELECT FOR UPDATE 就得等——看起来像“查得慢”,其实是卡在锁上
- 硬件或配置瓶颈:磁盘 I/O 慢、内存不足导致频繁刷脏页、sort_buffer_size 太小引发外排
排查思路建议
别一上来就加索引。先做这几步:
- 用 SHOW PROCESSLIST 或 pg_stat_activity 看慢查询是否正在运行、卡在哪(Sending data?Locked?)
- 拿到完整 SQL,用 EXPLAIN ANALYZE 对照实际耗时和预估
- 检查 WHERE、JOIN、ORDER BY、GROUP BY 中涉及的字段,再判断是否需要组合索引、覆盖索引或函数索引
- 确认数据量级变化——昨天快,今天慢?可能是某张表暴涨了十倍,而索引结构没适配










