联合索引(复合索引)建得合不合理,直接决定了查询能不能“走索引”、走得好不好。下面从原则、常见场景、避坑点三个层面讲清楚。
联合索引 (a, b, c) 相当于建立了:
(a)(a, b)(a, b, c)只有从最左边开始用,才能用上索引。
✅ 能用到索引:
WHERE a = 1
WHERE a = 1 AND b = 2
WHERE a = 1 AND b = 2 AND c = 3
❌ 用不到或只能用一部分:
WHERE b = 2
WHERE b = 2 AND c = 3
(a区分度高, b区分度低)
比如:
user_id(高)status(低)✅ 推荐:
INDEX(user_id, status)
原因:先快速缩小数据范围。
如果业务里 几乎总是带 user_id 查,那 user_id 必须在最左。
WHERE user_id = ? AND created_at > ?
→ INDEX(user_id, created_at)
⚠️ 范围查询(>, <, BETWEEN, LIKE 'xx%')会中断后续索引使用
WHERE a = 1 AND b > 10 AND c = 2
INDEX(a, b, c)
实际只用到了 (a, b),c 用不上。
✅ 更好的方式:
INDEX(a, c, b)
WHERE a = 1 ORDER BY b
INDEX(a, b)
✅ 能避免 filesort
❌ 错误示例:
ORDER BY b, a
INDEX(a, b)
GROUP BY a, b
INDEX(a, b)
user_id, status, created_at
查询:
WHERE user_id = ? AND status = ? ORDER BY created_at
✅ 索引:
INDEX(user_id, status, created_at)
app_id, level, created_at
查询:
WHERE app_id = ? AND created_at BETWEEN ? AND ?
✅ 索引:
INDEX(app_id, created_at)
❌ 在索引列上使用函数
WHERE DATE(created_at) = '2024-01-01'
→ 索引失效
✅ 改写为:
WHERE created_at >= '2024-01-01'
AND created_at < '2024-01-02'
❌ 隐式类型转换
WHERE user_id = '123' -- user_id 是 int
→ 可能不走索引
❌ 索引字段太多
高频 WHERE → 高区分度 → 等值 → 范围 → ORDER BY
如果你愿意,可以把:
发给我,我可以直接帮你设计最优联合索引。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。