MySQL升级至8.0后索引问题核心在于统计信息滞后、降序索引语义变化、ALGORITHM=INPLACE空间策略差异及工具兼容性不足,需手动刷新统计、重建混合排序索引、评估空间并谨慎使用检测工具。

MySQL 升级后 INFORMATION_SCHEMA.STATISTICS 显示的索引统计可能过期
MySQL 5.7 升级到 8.0 后,ANALYZE TABLE 不再自动触发采样更新(尤其在 innodb_stats_auto_recalc=OFF 或表无变更时),导致优化器仍用旧统计选择低效执行计划。这不是“索引损坏”,而是统计信息滞后。
- 检查是否启用自动重算:
SELECT @@innodb_stats_auto_recalc;
若为
OFF,需手动触发或改配置 - 强制刷新单表统计:
ANALYZE TABLE `orders`;
注意:该操作会加 MDL 读锁,大表慎在高峰执行
- 升级后建议批量刷新:生成脚本遍历所有表,跳过
information_schema和系统库
8.0 中 descending index 支持让旧复合索引可能失效
MySQL 8.0 支持在 CREATE INDEX 中显式指定 DESC,而 5.7 实际忽略该关键字、全按升序存储。若原查询依赖 ORDER BY a DESC, b ASC,5.7 下建的 INDEX idx(a,b) 可能被复用;但 8.0 优化器更严格匹配排序方向,可能放弃使用该索引。
- 用
EXPLAIN对比升级前后执行计划,重点关注key_len和Extra是否出现Using filesort - 对含混合排序方向的查询,重建索引:
CREATE INDEX idx_orders_status_created ON orders (status DESC, created_at ASC);
- 注意:8.0 的降序索引不兼容 5.7,回滚版本前需删掉这类索引
ALTER TABLE ... ALGORITHM=INPLACE 在 8.0 中对索引重建更激进
MySQL 8.0 默认启用 innodb_defragment=ON 和更强的页合并策略,ALGORITHM=INPLACE 重建索引时可能触发 B+ 树重组、填充因子调整,导致磁盘空间临时增长 2–3 倍——这和 5.7 的“就地”行为不一致。
机械设备钢材建材网站是基是一个以PHP+MySQL/Sqlite进行开发的四网合一网站源码。 系统功能特点: 四网合一企业网站管理系统支持在线升级(支持跨版本)、插件在线安装、系统内置严格的过滤体系、可以有效应对安全检测报告。 四网合一:电脑网站、手机站(数据同步、支持绑定域名)、小程序、公众号管理一个后台即可搞定。 双数据库引擎、运行环境全面:同时支持Sqlite
- 重建前确认空闲空间:
SELECT table_schema, table_name, round(((data_length + index_length) / 1024 / 1024), 2) AS size_mb FROM information_schema.tables WHERE table_schema = 'mydb' ORDER BY size_mb DESC LIMIT 5;
- 对超大表,改用
ALGORITHM=COPY+LOCK=NONE(需确保 binlog_format=ROW)更可控 - 避免在
innodb_file_per_table=OFF的老实例上重建,否则索引数据写入系统表空间,无法释放
升级后 pt-duplicate-key-checker 可能误报“冗余索引”
Percona Toolkit 的 pt-duplicate-key-checker 基于索引列前缀匹配判断冗余,但 MySQL 8.0 引入隐藏主键(row_id)、函数索引、不可见索引等新特性,工具未适配时会把 UNIQUE KEY (email) 和 INDEX (email, created_at) 判定为冗余,而实际业务中后者用于范围查询,不可删。
- 运行时加
--no-clustered跳过聚簇索引逻辑干扰 - 人工核验每条建议:用
SHOW CREATE TABLE看索引类型、可见性、表达式内容 - 特别注意函数索引:
INDEX idx_lower_name ((LOWER(name)))不会被传统索引覆盖,不能简单删除
升级后的索引问题,核心不在“重建动作本身”,而在统计信息、排序语义、空间策略、工具兼容这四个层面的隐性变化。最容易被忽略的是 ANALYZE TABLE 的效果衰减和降序索引的语义漂移——它们不会报错,但会让慢查询在升级后突然出现。