SQL索引需用对地方,优先为WHERE、ORDER BY、GROUP BY、JOIN ON字段创建,高区分度字段更优,复合索引遵循最左前缀原则,避免频繁更新字段,建前须用EXPLAIN验证执行计划。

SQL索引不是加得越多越好,关键在“用对地方”。创建前先看查询条件、排序字段和连接列,再结合数据分布和更新频率做判断——选错字段或滥用索引反而拖慢写入、浪费空间。
哪些字段适合建索引?
高频出现在 WHERE、ORDER BY、GROUP BY 和 JOIN ON 后的字段优先考虑。比如用户表常按 status 筛选、按 created_at 排序,这两个字段就值得建索引。
- 区分度高的字段效果更好(如
user_id比gender更适合单列索引) - 复合索引要遵循“最左前缀原则”:
(a, b, c)能加速a、a,b、a,b,c的查询,但对b或b,c无效 - 避免对频繁更新的字段建索引(如每秒更新的计数器),维护成本高
怎么创建高效复合索引?
把过滤性最强的字段放最左边,排序/分组字段放右边。例如查询:SELECT * FROM orders WHERE user_id = ? AND status = 'paid' ORDER BY created_at DESC,推荐索引:INDEX (user_id, status, created_at)。
- 如果
user_id本身已建主键或唯一索引,可只建(status, created_at) - 覆盖索引更省事:把
SELECT中的字段也加进索引末尾(如(user_id, status, created_at, amount)),避免回表查数据行 - 注意字段顺序不能随意调换,
(status, user_id)对WHERE user_id = ?就没用
建索引前必须做的三件事
别急着 CREATE INDEX,先确认它真能起作用。
- 用
EXPLAIN(MySQL)或EXPLAIN QUERY PLAN(SQLite)看执行计划,确认是否走了索引、有没有Using filesort或Using temporary - 检查表数据量和选择率:小表(如80%(如
is_deleted大多为0)建索引意义不大 - 观察慢查询日志,优先优化真正卡顿的语句,而不是凭感觉加索引
常见坑和替代方案
索引不是万能解药。有些场景更适合其他方式:
-
LIKE '%关键词' 无法用索引,考虑全文索引(
FULLTEXT)或倒排表 - 函数操作会让索引失效:
WHERE YEAR(created_at) = 2024→ 改成WHERE created_at >= '2024-01-01' AND created_at - 大量
OR条件可能走不了索引,试试拆成UNION或重写逻辑 - 实在没法优化的复杂查询,缓存结果或预计算聚合表可能比硬扛索引更有效
基本上就这些。索引本质是空间换时间,核心逻辑就一条:让数据库少扫描、少排序、少回表。动手前多看执行计划,上线后留意慢日志,不复杂但容易忽略。










