数据库索引不是越多越好,这几个关键点要注意下

举报
茉莉风铃 发表于 2026/10/10 10:20:53 2026/10/10
【摘要】 很多人一遇到查询慢就无脑加索引,结果写入变慢、磁盘吃紧。本文用一张"全表扫描 vs 索引查找"的对比图,讲清索引到底快在哪、又贵在哪,以及我踩过的真实坑。

刚学数据库那会,我有个迷之操作:只要哪里查得慢,就加索引。加着加着表上十几个索引,查询是快了点,但写入直接拖垮,磁盘也莫名其妙涨。后来被前辈骂了一顿才明白——索引是"用空间换时间",不是免费的午餐。

一、索引到底快在哪

不用索引时,数据库要找一条记录,基本是全表扫描:从第一行开始,一行行比对,直到找到。表里一千万行,最坏就得比一千万次。数据越大越慢,复杂度 O(n)。

加了索引(通常是 B+ 树),相当于给数据建了本"有序字典"。数据库不用逐行翻,顺着树几跳就定位到目标行,复杂度降到 O(log n)。一千万行的表,树也就跳个二十几层不到,差距天壤之别。

image.png

二、但它贵在哪,很多人不想

天下没有白拿的快。索引的代价:

  • 占空间。每个索引都是额外的一份数据结构,表大了索引可能比数据还占地方。
  • 拖慢写入。你每插一条、改一条,相关的索引也得跟着更新。索引越多,写越慢。我那次就是索引加太多,批量导入直接慢了三倍。
  • 可能用不上。索引建了不等于一定会用。比如对字段套了函数 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 看看现有索引够不够。

四、现在我怎么加索引

摸索出一套朴素原则:

  1. 先看慢查询日志,别凭感觉加。到底哪条 SQL 慢,拿数据说话。
  2. EXPLAIN 一下,确认到底走没走索引、走的哪个。这是基本功,不会这个就是盲加。
  3. 区分度高的列优先(用户 id、订单号这种),低区分度的(状态、性别)谨慎。
  4. 联合索引注意顺序,把最常用、区分度最高的放前面。
  5. 写多读少的表,索引能少就少。别为了偶尔一次查询,拖垮日常写入。

一句话:索引是药,对症才管用,可不能当饭吃。

总结

数据库优化这块,索引只是其中一环。很多时候查询慢,根子不在索引,而在烂 SQL、缺缓存、或者表设计本身就有问题。索引能救急,但救不了烂设计。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。