迁移后性能退化的常见原因
数据迁移后性能下降,90%的情况源于以下三点:
- 索引碎片化:大量随机插入导致B+树页分裂,填充因子下降。
- 统计信息过期:优化器基于旧数据分布生成执行计划,导致索引选择错误。
- 缓冲池冷启动:目标库的
innodb_buffer_pool中无热数据,首次查询需从磁盘读取。
因此,迁移后必须执行一套系统化的验证与优化流程。
第一步:重建索引与更新统计信息
对于InnoDB表,推荐使用ALTER TABLE tbl ENGINE=InnoDB重建表,该操作会整理数据页并重建所有索引。注意此操作会锁表,建议在维护窗口执行。若无法接受锁表,可使用pt-online-schema-change执行无锁重建。
随后执行:
ANALYZE TABLE tbl;该命令会扫描索引并更新information_schema.statistics,使优化器获得准确基数。对于超大表,可设置innodb_stats_persistent_sample_pages=64提高采样精度(默认20)。
第二步:预热缓冲池
迁移后首次查询性能差,是因为缓冲池为空。预热方法:
- 开启
innodb_buffer_pool_dump_at_shutdown=ON和innodb_buffer_pool_load_at_startup=ON,但迁移场景不适用。 - 手动执行全表扫描:
SELECT COUNT(*) FROM tbl;,将数据页载入内存。 - 使用
pt-query-digest分析迁移前的慢查询日志,提取高频访问的行,用SELECT * FROM tbl WHERE id IN (...)预热。
预热后,通过SHOW ENGINE INNODB STATUS查看Buffer pool hit rate,应高于99%。
第三步:基准查询对比回归测试
建立迁移前的性能基线(在源库执行),迁移后在目标库执行相同SQL,对比执行时间与执行计划。建议覆盖以下类型:
- 点查:
SELECT * FROM tbl WHERE id = ? - 范围查:
SELECT * FROM tbl WHERE create_time BETWEEN ? AND ? - 聚合查:
SELECT COUNT(*), SUM(amount) FROM tbl GROUP BY user_id - 多表JOIN:模拟核心业务关联查询。
对比EXPLAIN输出,重点检查type列(应为ref或range而非ALL),以及rows估算值是否与源库一致。
第四步:识别并优化新出现的慢SQL
使用SET GLOBAL slow_query_log=ON开启慢查询日志,设置long_query_time=1,运行24小时后分析:
pt-query-digest /var/log/mysql/slow.log | head -20针对Top慢SQL,常见优化手段:
- 若索引未被使用,检查
cardinality是否过低,考虑强制索引FORCE INDEX。 - 若为范围查询,考虑使用
covering index(覆盖索引)减少回表。 - 若为排序查询,确保
ORDER BY字段与索引顺序一致。
第五步:大表分区策略评估
若迁移后单表仍超过200GB,且查询条件多基于时间或范围,可考虑分区。示例:
ALTER TABLE tbl PARTITION BY RANGE (YEAR(create_time)) (PARTITION p2020 VALUES LESS THAN (2021), PARTITION p2021 VALUES LESS THAN (2022), PARTITION p2022 VALUES LESS THAN (2023), PARTITION p_future VALUES LESS THAN MAXVALUE);分区带来的好处:
- 分区裁剪:查询只扫描相关分区,减少IO。
- 方便归档:可直接
DROP PARTITION删除旧数据。 - 并行扫描:多分区可并行读取。
注意:分区键必须包含在主键或唯一键中,且分区数不宜超过1024。
第六步:持续监控与调优
迁移后一周内,每日检查:
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_waits',确认锁竞争是否正常。SHOW ENGINE INNODB STATUS中的History list length,若持续增长说明purge线程滞后。- 使用
performance_schema查询events_statements_summary_by_digest,找出高频高耗时语句。
最后,建议将目标库的innodb_buffer_pool_size设置为物理内存的70%,并开启innodb_flush_log_at_trx_commit=2(允许丢失1秒事务)以提升写入性能。
通过上述六步,可确保大表迁移后不仅数据完整,性能也达到或超过迁移前水平。