数据库索引不是越多越好,这几个关键点要注意下
【摘要】 很多人一遇到查询慢就无脑加索引,结果写入变慢、磁盘吃紧。本文用一张"全表扫描 vs 索引查找"的对比图,讲清索引到底快在哪、又贵在哪,以及我踩过的真实坑。
刚学数据库那会,我有个迷之操作:只要哪里查得慢,就加索引。加着加着表上十几个索引,查询是快了点,但写入直接拖垮,磁盘也莫名其妙涨。后来被前辈骂了一顿才明白——索引是"用空间换时间",不是免费的午餐。
一、索引到底快在哪
不用索引时,数据库要找一条记录,基本是全表扫描:从第一行开始,一行行比对,直到找到。表里一千万行,最坏就得比一千万次。数据越大越慢,复杂度 O(n)。
加了索引(通常是 B+ 树),相当于给数据建了本"有序字典"。数据库不用逐行翻,顺着树几跳就定位到目标行,复杂度降到 O(log n)。一千万行的表,树也就跳个二十几层不到,差距天壤之别。

二、但它贵在哪,很多人不想
天下没有白拿的快。索引的代价:
- 占空间。每个索引都是额外的一份数据结构,表大了索引可能比数据还占地方。
- 拖慢写入。你每插一条、改一条,相关的索引也得跟着更新。索引越多,写越慢。我那次就是索引加太多,批量导入直接慢了三倍。
- 可能用不上。索引建了不等于一定会用。比如对字段套了函数
WHERE YEAR(created_at)=2026,或者用了LIKE '%关键字'(前缀通配),索引基本就废了,还是全表扫。
三、我踩过的几个具体坑
坑 1:在低区分度字段上加索引。 比如"性别"这种只有男/女两值的列,加索引几乎没用——数据库一算发现一半数据都符合,还不如全表扫。这种字段建索引纯浪费。
坑 2:索引建了但查询没命中。 有次慢查询,我确认字段有索引,结果一 EXPLAIN 发现走的是全表。原因是对那个字段做了函数计算,索引失效。改成范围查询后才用上。
-- 慢:对列套函数,索引用不上
SELECT * FROM orders WHERE DATE(create_time) = '2026-08-25';
-- 快:改成范围,能用上 create_time 的索引
SELECT * FROM orders
WHERE create_time >= '2026-08-25 00:00:00'
AND create_time < '2026-08-26 00:00:00';
坑 3:重复和冗余索引。 有时候 (a,b) 的联合索引已经能覆盖只查 a 的场景,我又单独建了个 a 的索引,纯冗余。建之前先用 EXPLAIN 看看现有索引够不够。
四、现在我怎么加索引
摸索出一套朴素原则:
- 先看慢查询日志,别凭感觉加。到底哪条 SQL 慢,拿数据说话。
EXPLAIN一下,确认到底走没走索引、走的哪个。这是基本功,不会这个就是盲加。- 区分度高的列优先(用户 id、订单号这种),低区分度的(状态、性别)谨慎。
- 联合索引注意顺序,把最常用、区分度最高的放前面。
- 写多读少的表,索引能少就少。别为了偶尔一次查询,拖垮日常写入。
一句话:索引是药,对症才管用,可不能当饭吃。
总结
数据库优化这块,索引只是其中一环。很多时候查询慢,根子不在索引,而在烂 SQL、缺缓存、或者表设计本身就有问题。索引能救急,但救不了烂设计。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)