会,mysqldump --tables 默认导出所有表结构中定义的索引(含主键、唯一键、普通索引),因其实质读取当前 show create table 结果;但需注意版本兼容性、排序规则一致性及隐式索引字段顺序。

mysqldump 用 --tables 提取多张表时,索引会自动包含吗?
会,但仅限于表结构级索引(即 CREATE TABLE 语句中定义的索引),不包括后续用 ALTER TABLE ADD INDEX 单独创建的索引——除非你加了 --no-create-info 或 --skip-add-drop-table 等干扰选项。
默认情况下,mysqldump --databases db_name --tables t1 t2 t3 输出的 SQL 包含:CREATE TABLE(含主键、唯一键、普通索引)、INSERT、以及每个表末尾的 /*!40000 ALTER TABLE ... ENABLE KEYS */。这意味着所有在建表语句里声明的索引都会被重建。
- 如果某张表后来通过
ALTER TABLE t1 ADD INDEX idx_x (x)加了索引,且 dump 时没加--no-create-info,这个索引仍会被包含——因为mysqldump读的是当前SHOW CREATE TABLE的结果,不是原始建表语句 - 但如果你用的是老版本 MySQL(如 5.6)且表使用 MyISAM,
ENABLE KEYS可能因引擎差异失效,导致索引没真正建上 -
--skip-extended-insert不影响索引导出,只影响 INSERT 格式;而--compact会删掉注释和分隔符,可能让索引定义更难定位
如何确保迁移后索引名、类型、字段顺序完全一致?
靠 mysqldump 默认行为基本可以,但有三个关键点必须手动校验:
- 执行前先在源库运行
SHOW CREATE TABLE t1\G,复制出索引定义行(如KEY idx_user_id (user_id)),和 dump 文件里对应位置逐字比对 - 注意隐式索引:比如
UNIQUE KEY和PRIMARY KEY在 dump 中是显式写的,但联合索引字段顺序错一位(如(a,b)写成(b,a))会导致查询无法命中 - 如果目标库 MySQL 版本低于源库(例如从 8.0 dump 到 5.7),某些新特性索引(如函数索引
INDEX ((UPPER(name))))会被忽略或报错,dump 时不会警告,只会在导入时报ERROR 1064
跳过某些表的索引只导数据,或跳过某些索引只导结构?
不能直接跳过单个索引,但可以通过组合参数控制粒度:
- 只要数据不要索引:用
mysqldump --no-create-info --skip-triggers --skip-extended-insert db_name t1 t2,这样输出只有INSERT,无任何CREATE或索引语句 - 只要结构不要数据:用
mysqldump --no-data --skip-triggers db_name t1 t2,它会导出完整CREATE TABLE(含所有索引),但不带INSERT - 想剔除某个特定索引?只能人工编辑 dump 文件,删掉对应
KEY行——别动PRIMARY KEY,否则导入会失败;也别删掉外键约束相关索引,否则FOREIGN KEY无法创建
导入时索引重建慢,有没有更高效的方式?
大表迁移时,索引重建常占 70%+ 时间。提速的关键不是绕过索引,而是控制重建时机:
- 在目标库导入前加
SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0;,导入后再恢复——这能让 InnoDB 暂停唯一性检查和外键验证,加速INSERT和索引构建 - 如果 dump 文件里已有
DISABLE KEYS / ENABLE KEYS,确保目标表引擎是 MyISAM;InnoDB 忽略这两句,此时应改用--innodb-optimize-keys(MySQL 5.7+)让 mysqldump 把索引建在最后 - 避免在导入过程中执行
ANALYZE TABLE,它会触发额外统计收集;等全部导入完成再统一跑一次即可
最易被忽略的是字符集与排序规则不一致:如果源表用 utf8mb4_0900_as_cs,目标库默认是 utf8mb4_general_ci,即使索引字段相同,也可能因 collation 差异导致索引实际不可用——导入后务必核对 SHOW CREATE TABLE 输出里的 COLLATE 字段。











