索引降低写入性能,本质是这几笔开销

索引降低写入性能本质是这几笔开销——这话我跟人重复过太多次了。多数人的第一反应是把索引砍了,写是快了,读接口先顶不住。所以别急着删,先弄明白写一条数据的时候,数据库到底替你干了多少活,哪些是必须的,哪些是你自己给自己加的。

性能优化

一次 insert 落地,索引那边要动几下手脚

表上只有一个聚簇索引的时候,写一条记录还算轻省:在B+树上找到该去的位置,写进数据页,改页目录,记redo,脏页排着队等刷盘。就这样已经是一串动作了。你再加三个二级索引,同一条insert就得在几棵树上各找一次位置、各写一次;要是这几个索引页还不在同一片区域,那基本等于几次随机写。写入放大这词听着玄,落到磁盘上就是多了几份数据,落到内存里就是多了几份脏页。

还有一种情况常被忽略:update。改的是非索引列,二级索引基本不用动,InnoDB 这类引擎有 in-place 更新,代价小得多;改的偏偏是索引列,那就是旧的删一条、新的插一条。所以“我这表更新特别慢”这句话,得先追问一句改的是哪个字段。同一条 SQL,改不同列,成本差得很远。

索引降低写入性能本质是这几笔开销,先认全再谈优化

拆开看大概五笔账,认全了才知道该动哪一笔。第一笔是随机IO,索引越多,写入时被打散的页就越多。第二笔是页分裂,后面单独说。第三笔是唯一性校验,唯一索引和主键在写之前必须确认没有重复,这一步本质是一次读,写操作里硬生生插进去一次查找。第四笔是缓存,缓冲池大小是固定的,索引页占得多,数据页就少,热数据被挤出去,读写一起遭殃。第五笔是日志和刷脏,redo、undo都要跟着写,脏页多了刷盘那一下的抖动也会明显。这五笔里,前三笔跟索引数量直接挂钩,后两笔是连锁反应。

顺带说一句,很多人一上来就想找参数调优,把刷脏节奏调快点、把日志缓冲加大点。能缓一缓,但治不了根。索引本身就是写放大源头,参数只是让它别那么难受。

页分裂这玩意儿,比你想的常见

自增主键顺序插入,页慢慢填满,填满了开新页,很顺。换成UUID、雪花ID里的随机段、或者业务上那种没规律的编号做主键,插入点就撒在整棵树里,每次落点都可能把一个已经装满的页劈成两半:申请新页、把一半数据挪过去、更新父节点的指针。分裂之后页的填充率掉下来,同样的数据量占的页更多,扫描要多读几页,刷盘也多写几页。碎片攒久了,你会觉得“数据没涨多少,磁盘和IO先涨了”。

这一笔开销跟索引数量关系不大,跟主键选型关系极大。写多读少、量又上得快的表,主键老老实实用有序值,能省掉一大截。业务上非要用UUID的,也有折中办法,比如有序UUID,各家实现不一样,具体以你用的数据库版本文档为准。

唯一索引,代价藏在“校验”那两个字里

唯一索引除了维护树结构,还要保证不重复。写进去之前得去查一遍,这一步在并发写入的时候还要加锁等一等,热点值上尤其明显。有些人喜欢给手机号、邮箱、单号全都挂唯一索引,逻辑上是干净了,可每一次写入都带着一次额外的查找,量一上来就现形。是不是每个都得挂唯一约束,值得一个一个过一遍——有些重复完全可以在业务层或者入库前拦掉,不必让数据库每写一次就查一次。

索引一多,缓存里就装不下热数据

缓冲池就那么大,索引占的页多了,留给数据页的空间就少。命中率一掉,读变慢,刷脏也更频繁。这个坑隐蔽在于,你单看写压测的曲线未必看得出来,等线上读写混跑的时候才发作。所以评估索引不能只算“这个查询能快多少”,还得算它常驻内存占多少。

怎么确认这笔账记在索引头上

别拍脑袋删。先看慢日志,把写入慢的语句捞出来;再看看写操作的耗时分布,是不是集中在某几张表。MySQL 这边 performance_schema 和 sys 库里有索引使用情况的视图,能看出哪些索引一次都没被读过。pt-index-usage 这类工具可以对着慢日志反推索引使用率,pt-duplicate-key-checker 能揪出重复和冗余的索引。做完这些,再在测试环境上删掉一两个索引,压一遍写,对比前后。生产上直接删索引这事,除非你已经确认过没有查询依赖它。

能落地的减法,从删冗余开始

冗余索引是最容易捡的便宜:(a,b) 上已经有联合索引了,再单独建一个 (a) 就是白养。能合并的合并,靠最左前缀去覆盖原来那些单列查询。历史数据该归档就归档,冷表上的索引纯粹是负担。批量插入比一条一条插省很多,这个不用多说。写远多于读的表,索引数量真的要克制,一两个够用的就别加到五六个。

还有一句提醒:覆盖索引、索引下推这些,优化的是读,别拿来当写入优化的理由。方向搞反了,越优化越慢。

遇到写入变慢,先别怪机器、别怪磁盘。把表上的索引列出来,一个个问它:最近一个月被用过吗,是不是被别的索引覆盖了,这个唯一约束非数据库来管不可吗。三个问题问完,通常就能砍掉一两个。剩下的那些,才是你为了查询必须付的钱。

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

赞 (0)
爱家的头像爱家
网站AI自建还是买现成,差在后续维护
上一篇 2026-11-01 04:29
算力中心辐射——可能还不如你家路由器
下一篇 2026-11-01 05:35

相关推荐

  • 服务器重启后,为何仍存在一个存储过程?

    服务器重启后有一个存储过程,这通常意味着在服务器重新启动之后,需要执行一系列预定义的步骤来确保系统的稳定性和数据的完整性,这些步骤可能包括数据库恢复、日志清理、缓存重建等操作,为了更清晰地展示这一过程,我们可以将其分为几个关键部分,并使用表格形式来组织信息, 服务器重启前准备 步骤 描述 数据备份 确保所有重要……

    2024-12-18
    0014
  • 如何有效进行服务器错误排查?

    服务器错误排查是IT运维中的一项重要工作,它涉及到硬件故障、软件配置问题、网络连接异常等多个方面,为了确保服务器能够稳定运行,我们需要对这些问题进行及时的发现和处理,本文将详细介绍服务器错误排查的方法和步骤,帮助读者提高服务器维护能力,硬件故障排查1、电源问题:检查服务器电源是否正常工作,是否有损坏或接触不良的……

    2025-01-12
    0019
  • 如何根据需求选择合适的服务器类型?

    服务器选型说明一、性能与可扩展性在选择服务器时,首先需要考虑的是其性能和可扩展性,性能包括处理能力、存储容量以及网络带宽等方面的表现,可扩展性则指的是服务器在未来业务增长时的扩展能力,根据预计的负载和性能需求,选择具备充足计算能力和扩展潜力的服务器,以确保系统稳定和高效运行, 指标 描述 处理能力 根据业务需求……

    2024-11-05
    006
  • 负载均衡与HA有何区别?

    负载均衡(Load Balancing,LB)与高可用性(High Availability,HA)是两个在IT和网络架构中至关重要的概念,尽管它们都旨在提高系统的可靠性和稳定性,但它们的关注点和实现方式有所不同,一、负载均衡1、定义:负载均衡是一种技术解决方案,用来在多个资源中分配负载,达到最优化资源使用,避……

    2024-12-16
    0016

发表回复

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

广告合作

QQ:14239236

在线咨询: QQ交谈

邮件:asy@cxas.com

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

关注微信