索引会拖慢写入速度,因每次INSERT/UPDATE/DELETE均需同步更新所有相关索引,引发额外CPU、I/O及锁开销;宽索引、低选择性索引、重复索引和未使用索引维护成本最高。

索引能加速查询,但不是越多越好——每增加一个索引,写入(INSERT/UPDATE/DELETE)操作就要多维护一份数据结构,带来额外的CPU、I/O和锁开销。
索引如何拖慢写入速度
每次写入时,数据库不仅要更新表数据,还要同步更新所有相关索引:
- INSERT:除插入主表行外,还需为每个索引构造并插入新索引项,B+树可能触发页分裂
- UPDATE:若修改的是被索引列,原索引项要删除、新索引项要插入;非索引列更新则只影响主表
- DELETE:主表行标记删除后,所有对应索引项也必须定位并清除
尤其在高并发写入场景下,多个会话争用同一索引页,容易加剧锁等待或latch竞争。
哪些索引最“贵”?
维护成本差异明显,重点关注以下几类:
- 宽索引:包含多个VARCHAR(500)或TEXT列的复合索引,不仅体积大,排序和比较开销也高
- 低选择性索引:如对性别、状态(只有'Y'/'N')建索引,查询收益极小,但写入时照常维护
- 重复索引:(a,b) 和 (a,b,c) 同时存在,后者基本覆盖前者功能,徒增写入负担
- 未被使用的索引:长期无查询走访问,纯属“写入税”,应定期清理(可通过 pg_stat_all_indexes 或 sys.dm_db_index_usage_stats 识别)
平衡策略:让索引更聪明
不靠删索引,而靠精准设计和动态管理:
- 优先使用覆盖索引:把常用查询的SELECT列加入INCLUDE(SQL Server)或作为索引尾部列(PostgreSQL),避免回表,减少必要索引数量
- 延迟维护:批量写入时,可考虑先禁用非关键索引(如 ALTER INDEX ... DISABLE),导入完成后再重建
- 区分读写负载:OLTP系统慎用全文索引、函数索引等重型索引;高频更新字段尽量避免单独建索引
- 监控实际效果:用执行计划确认查询是否真正用到某索引,而不是仅凭“看起来有用”就保留
索引是性能杠杆,关键在支点位置——写入压力大的表,宁可少而精,不求全责备。











