ALTER TABLE t ENGINE=InnoDB会重建整张表及所有索引,消除碎片、重排B+树,但需SX锁、阻塞DML;OPTIMIZE TABLE在InnoDB中等价于此操作;单索引重建推荐DROP INDEX+CREATE INDEX;统计信息过期应优先ANALYZE TABLE。

ALTER TABLE ... ENGINE=InnoDB 会重建所有索引
对 InnoDB 表执行 ALTER TABLE t ENGINE=InnoDB(即使引擎没变),MySQL 会重建整张表,包括所有二级索引和聚簇索引。这是最彻底的“重建索引”方式,能消除页分裂、释放碎片空间、重排 B+ 树结构。
但要注意:该操作会加 SX(共享读写)锁,阻塞 DML(INSERT/UPDATE/DELETE),且耗时与表大小正相关。线上大表慎用,建议在低峰期配合 pt-online-schema-change 或 MySQL 8.0+ 的 ALGORITHM=INPLACE 可选参数控制。
- MySQL 5.6+ 支持部分
ALTER操作为INPLACE,例如ADD INDEX或DROP INDEX不触发全表重建 -
OPTIMIZE TABLE t在 InnoDB 中等价于ALTER TABLE t ENGINE=InnoDB,效果相同 - MyISAM 表上
OPTIMIZE TABLE才真正“整理碎片”,InnoDB 下它只是重建
DROP INDEX + CREATE INDEX 是最可控的单索引重建方式
如果只怀疑某个二级索引损坏或严重膨胀(比如 cardinality 明显偏低、data_length 异常高),直接删掉再建更轻量、影响更小。
执行前先确认索引名:
SHOW INDEX FROM t;然后执行:
DROP INDEX idx_name ON t; CREATE INDEX idx_name ON t (col1, col2);
注意点:
- MySQL 5.7+ 默认允许并发 DML,但
DROP INDEX仍需短暂元数据锁(MDL),一般毫秒级 - 重建过程中,该索引不可用,查询若强制走这个索引会报错
Unknown index - 务必核对
CREATE INDEX的列顺序、排序方向(ASC/DESC)、前缀长度(如name(10)),否则语义可能改变
使用 ANALYZE TABLE 更新索引统计信息,不重建但影响查询计划
索引本身没坏,但优化器选错了执行路径?大概率是统计信息过期。ANALYZE TABLE 不重建索引,只采样页并更新 information_schema.STATISTICS 中的 cardinality 值。
由于疫情等原因大家都开始习惯了通过互联网上租车服务的信息多方面,且获取方式简便,不管是婚庆用车、旅游租车、还是短租等租车业务。越来越多租车企业都开始主动把租车业务推向给潜在需求客户,所以如何设计一个租车网站,以便在同行中脱颖而出就重要了,易优cms针对租车行业市场需求、目标客户、盈利模式等,进行策划、设计、制作,建设一个符合用户与搜索引擎需求的租车网站源码。 网站首页
它快(毫秒级)、无锁(只读锁),适合日常维护:
ANALYZE TABLE t;
常见触发场景:
- 表数据量突增 > 10% 且未做
ANALYZE -
EXPLAIN显示用了错误索引,而SHOW INDEX查到该索引Cardinality为 1 或远低于实际唯一值数量 - 升级 MySQL 版本后首次运行查询,旧统计信息不兼容新优化器逻辑
误删索引后恢复:靠备份或 SHOW CREATE TABLE
手抖执行了 DROP INDEX 又没记下定义?别急着 panic。
如果表结构没变过,SHOW CREATE TABLE t 能还原当前所有索引定义(包括隐式主键);如果已改过结构,且没有逻辑备份(如 mysqldump --no-data),就只能从最近一次备份里提取 CREATE INDEX 语句。
关键提醒:
- MySQL 不记录索引创建时间,
information_schema里查不到历史 DDL - binlog 是行格式(ROW)时,不包含索引变更事件;只有 STATEMENT 格式才可能在日志里看到
DROP/CREATE INDEX,但不可靠 - 生产库建议定期导出
SHOW CREATE TABLE结果存档,比依赖记忆靠谱得多
SHOW INDEX 和 EXPLAIN 定位真实瓶颈,比盲目 OPTIMIZE 有用得多。









