MySQL索引重建策略

先说说为啥要重建索引。简单讲,索引用久了会“散架”。比如频繁的增删改操作,会让索引页出现空洞,数据物理顺序混乱,甚至导致索引统计信息过期。MySQL优化器依赖这些统计信息来选执行计划,如果信息不准,它可能选错索引,直接拖慢查询。举个例子,有个订单表每天新增几十万条,原本走索引的范围查询,突然变成了全表扫描——一查才知道,索引基数(cardinality)估值偏差太大。这时候,光靠更新统计信息可能不够,必须彻底重建索引。

MySQL重建索引主要有两种方式:隐式重建和显式重建。隐式重建是通过命令实现的,它相当于对表做一次“大扫除”——不仅重建索引,还会整理数据碎片,相当于InnoDB的碎片整理工具。执行起来很简单:

但要注意,这命令会锁表,写操作会被阻塞,所以最好在业务低峰期干。另外,对于InnoDB引擎,本质上是将表数据导出一遍再导入,磁盘空间不够的话可能爆掉,务必提前检查。

显式重建更灵活,适合针对性优化。比如单独重建某个索引,可以用:

先删后建,相当于重新生成索引树。这种方法能精准控制,但缺点是删除索引期间,依赖这个索引的查询会全表扫描,如果表太大,临时性能抖动会很吓人。我曾经在午间流量低时操作一个亿级用户表,结果删除索引瞬间,CPU直接飙满——后来学乖了,先用工具在线操作,避免锁表。

什么时候该重建索引?别盲目!通常有几个信号:一是查询明显变慢,用看到“Using filesort”或“Using temporary”频繁出现;二是索引碎片率超过20%(用里的字段估算);三是大量批量删除后,索引空间没释放。但频率也别太高,否则反而增加负载。我们团队习惯每月低峰期整体巡检一次,结合监控脚本抓取慢查询日志,针对性重建。

重建策略得看业务场景。如果是OLTP高频交易系统,可以用分阶段重建:先建一个隐藏索引(MySQL 8.0支持不可见索引),测试无误后再切过去。没这功能的话,就建冗余索引——比如新增一个,数据同步完再重命名替换。对于分区表,还能按分区逐个重建,减少锁范围。记得有一次重建日志表索引,因为没分区,直接锁表半小时,客服电话都被打爆了……血泪教训啊!

重建后的优化也不容忽视。首先跑一遍更新统计信息,让优化器“认路”;其次用确认碎片率是否降到5%以内;最后压测关键查询,对比前后执行时间。我们常用sysbench模拟并发查询,观察QPS和延迟变化。还有个细节:重建后索引可能更紧凑,如果缓冲池(buffer pool)没预热,首次查询反而会慢。这时可以用强制走索引,或者提前加载热点数据到内存。

总之,索引重建不是银弹,而是权衡艺术。既要解决碎片问题,又得规避业务风险。核心原则就是:监控先行、低峰操作、有备无患。现在我们的数据库巡检清单里,索引健康度已是必查项,配合自动化脚本定期维护,总算告别了半夜被报警吵醒的日子。大家如果有更好的点子,欢迎拍砖补充!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值