Navicat 16 数据同步不导出索引,因其仅同步行级数据(INSERT/UPDATE/DELETE),不处理DDL;索引需通过Data Transfer勾选“结构”或手动执行CREATE INDEX语句补全,并配合ANALYZE TABLE更新统计信息。

Navicat 16 同步生产库到测试库时索引没导出,根本原因不是同步过程出错,而是“同步”功能本身不负责导出或重建索引——它只同步数据行,不处理 DDL 结构变更。
你看到的“同步完成”,实际只是 INSERT/UPDATE/DELETE 执行完毕;索引是否存在于目标库,完全取决于目标表当前结构,和同步操作无关。
为什么“数据同步”不带索引?
Navicat 的 Data Transfer 和 Data Synchronization 是两个独立功能:
-
Data Transfer(数据传输):可选“仅结构”“仅数据”“结构和数据”,勾选“结构”时才会建表+建索引; -
Data Synchronization(数据同步):默认只比对并同步行级差异,完全忽略索引、外键、触发器等 DDL 对象。
很多用户误把“同步”当“全量迁移”,结果目标库表空有数据、没有索引,查询立刻变慢甚至超时。
怎么确认目标库真缺索引?
别信 Navicat 左侧对象树里“索引”节点是否展开——它只是缓存渲染,可能滞后或不刷新。必须直查 MySQL:
- 在目标库执行:
SHOW INDEX FROM `users`;(注意反引号) - 如果返回空结果集,或只有
PRIMARY一行,说明二级索引确实缺失; - 对比源库执行同样语句,确认哪些
Key_name在目标库消失了。
常见漏索引场景:
- 源库用
ALTER TABLE ADD INDEX动态加的索引,但备份文件(.sql 或 .nb3)未包含该语句; - Navicat 还原时,“对象类型”没勾选“索引”;
- 同步前目标表已存在,但结构是手动建的或从旧脚本初始化的,压根没建索引。
补索引必须绕过图形界面
不要点开“设计表→索引→+号→填字段→保存”——这个流程极易失败:
- 联合索引列顺序被自动重排(比如你输
status, created_at,它生成created_at, status); - 字段名大小写不一致(MySQL 在严格模式下区分大小写)导致语法报错;
- 静默跳过重复索引创建,也不提示已存在同名索引;
- 对
TEXT字段自动加前缀但不显式声明,引发ERROR 1170。
可靠做法:在查询窗口手写标准语句,例如:
CREATE INDEX idx_orders_status_created ON orders(status, created_at) USING BTREE;
注意:
- 必须显式写
USING BTREE(MySQL 5.7+ 默认,但显式更稳); - 联合索引字段顺序要贴合高频 WHERE 条件(如常查
WHERE status = ? AND created_at > ?,顺序不能反); - 唯一索引用
CREATE UNIQUE INDEX,别漏UNIQUE关键字。
补完索引后还查不动?别忘了 ANALYZE TABLE
索引建好了,EXPLAIN 却显示 type: ALL、key: NULL?大概率是统计信息没更新:
- 大批量数据同步后,InnoDB 不会自动刷新索引基数(cardinality),优化器基于过期采样判断“走索引不如全表扫”;
- 执行:
ANALYZE TABLE orders;(毫秒级,无锁,比OPTIMIZE TABLE更轻量); - 再
EXPLAIN,key字段通常立刻亮起。
这一步 Navicat 不会帮你做,也不会在同步日志里提示——它只管数据落盘,不管查询性能是否回归。











