数据库写入变慢:索引才是隐形收费站

写入慢这件事,第一反应往往是磁盘扛不住了、CPU 撑爆了。真把监控拉出来看,磁盘 IO 没满,CPU 也就三四成,慢就慢在某条 INSERT 上,一条一条往里插还行,一上批量就卡住。绕一圈,问题常常落在索引身上——数据库写入变慢索引才是隐形收费站,这个说法听着像标题党,可排查过几回的人都知道它有多实在:每写一行数据,这台车都要上好几条匝道,挨个缴费。

数据库优化

数据库写入变慢索引才是隐形收费站,过路费收在哪

InnoDB 写一行,不是往表里塞完就完事。聚簇索引得按主键顺序把记录放到该在的页上,表上挂的每一个二级索引都要跟着改一遍,每个索引页还得维持键值有序。主键是顺序递增的还好,插入基本落在最后一页;主键是乱序的,插入位置就在整棵树里到处跳,页写满了就分裂,一个页劈成两个,碎片慢慢堆积起来。这些动作没人看见,但它们实打实占了写入时间。

所以一张表挂五个索引,插一条记录差不多就是六棵树同时被改动,另外还要写 redo、写 undo,事务提交时再刷盘。索引越多,这条缴费通道越长,单条写入的耗时就越难看。写入密集型的表,索引数量对性能的影响往往比换一块更快的盘还明显。

联合索引的顺序,比索引数量更容易踩坑

(a,b,c) 和 (c,b,a) 完全不是一码事,最左前缀那套规则多数人背过,真建索引的时候又忘了。顺序排得好,一个宽一点的联合索引能顶掉两三个单列索引,写入侧少维护两棵树;顺序排得乱,只能再补单列索引,白白多出几条匝道。比较常见的做法是把区分度高的列放前面,把范围查询的列放后面,具体还得照查询模式来,不能只看字段本身。

还有个细节,很多人喜欢给每个外键、每个状态位都单独建索引。状态位那种只有几个取值的列,单列索引的选择性很差,读的时候优化器未必用,写的时候却一次不落地维护。这类索引属于典型的收费不收钱、路还特别堵。

覆盖索引救的是读,不是写

覆盖索引确实好用,一条查询要的列全在索引里,不用回表,读性能直接上一个台阶。可它并不能让写入变轻松,索引里多一个列,每条记录的索引项就更宽,页能装的条目更少,树更高,分裂更频繁。有的表为了让某一条报表 SQL 免回表,硬加了一个宽联合索引,结果报表一天跑一次,写入却是一天几万次,这笔账怎么算都亏。

判断标准其实不复杂:读多写少的表,索引可以宽一点、多一点;写多读少的表,比如日志、订单流水、埋点记录,索引就该抠着来,够用就行。

怎么把藏在表里的收费站找出来

第一步是慢查询日志。long_query_time 调到能抓到问题语句的档位,先看清楚是哪些写入在拖时间,别上来就删索引。第二步看索引清单,SHOW INDEX FROM 表名,人眼扫一遍,最左列相同、前缀重复的基本就是冗余索引,两棵树的活其实一棵能干。表多的时候用 information_schema.statistics 拉出来批量比对,比一张张点开快得多。

第三步看使用情况。performance_schema 里的索引使用统计能告诉你哪些索引从建出来就没被读过;MySQL 8 之后还能把索引设成 INVISIBLE,先藏起来观察一阵,业务没报错再删。云数据库一般会在控制台给出慢日志和索引建议,具体口径和可用功能以服务商官方页面说明为准,别照着别人的截图操作。

批量导入的时候,索引可以晚点建

做数据迁移或者初始化数据,带着一堆二级索引往里灌是最慢的做法。常规套路是先建表结构、只留主键,数据全部导入之后再统一 ALTER TABLE ADD INDEX 把索引建起来,中间省掉的维护开销很可观。要注意的是唯一索引不能这么省,业务约束得靠它兜;另外建索引这一步本身也吃资源,挑业务低峰做,大表优先用 online DDL 或者专门的工具,别在高峰期锁住一张热表。

提交方式也有讲究。一个事务塞进去几十万行,undo 撑得老大,回滚段压力上来了,写入延迟跟着抖。拆成小批次提交,一批几千行,中间喘口气,整体反而更快。主键也别用随机字符串,UUID 那种无序值会让聚簇索引到处插,页分裂比自增主键严重得多,能自增就自增,分布式场景用有序的雪花类 ID。

最后给一份能直接照着走的清单:写密集的表先数一遍索引个数,超过业务需要的就砍;用 SHOW INDEX 找最左列重复的冗余索引,别凭感觉删,先看使用统计或者设成不可见观察几天;联合索引按查询模式排顺序,别给低区分度字段单独建索引;批量导入先导数据后建二级索引,唯一约束除外;主键用有序值,事务拆小批提交。索引本身不是坏东西,它只是收费——想清楚哪些路必须走、哪些匝道可以封掉,写入自然就顺畅了。

【版权声明】:本站内容若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!

赞 (0)
爱家的头像爱家
网站权重等级;域名老不等于权重高
上一篇 2026-11-02 06:20
抚州市vps租用
下一篇 2025-04-01 15:07

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

广告合作

QQ:14239236

在线咨询: QQ交谈

邮件:asy@cxas.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信