Navicat 15 结构同步完全不识别联合索引,因其元数据采集逻辑未聚合 INFORMATION_SCHEMA.STATISTICS 中 SEQ_IN_INDEX > 1 的多列字段,导致静默跳过而非报错。

结构同步时联合索引完全不显示在差异列表中
Navicat 15 的结构同步(Synchronize Structure)默认只比对单列索引、主键、外键和基本表结构,KEY 和 UNIQUE KEY 定义中的多列组合(即联合索引)常被跳过——不是你没建,是 Navicat 根本没读进来。
根本原因在于其元数据采集逻辑:它依赖 INFORMATION_SCHEMA.STATISTICS,但对 SEQ_IN_INDEX > 1 的后续字段不做聚合处理。比如你建了 INDEX idx_user_status_created (user_id, status, created_at),Navicat 可能只识别出 user_id 这一列,其余两列被忽略,最终判定“无差异”。
- 验证方式:在目标库执行
SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'your_table' AND INDEX_NAME = 'idx_user_status_created' ORDER BY SEQ_IN_INDEX;,确认是否有多行返回;若有多行却未同步,就是 Navicat 解析缺陷 - 临时绕过:手动在目标库执行
CREATE INDEX idx_user_status_created ON your_table (user_id, status, created_at);,再重新运行结构同步——Navicat 会把“已存在”当作一致,不再报错,但也不会帮你补漏 - 升级替代方案:Navicat 16+ 改写了索引解析器,能正确聚合
SEQ_IN_INDEX字段,识别完整联合索引定义
预览差异时联合索引显示为“删除”,但源库实际存在
这种反向误判,通常发生在源库使用了 MySQL 8.0+ 新增的索引可见性(VISIBLE/INVISIBLE)或降序索引(DESC),而 Navicat 15 驱动无法解析这些属性,导致比对时把“源有、目标无”的索引当成“源删、目标留”。
- 典型触发场景:
CREATE INDEX idx_order_time ON orders (order_time DESC);或CREATE INDEX idx_archived INVISIBLE ON users (archived); - 检查方法:在源库执行
SHOW CREATE TABLE orders;,看索引定义是否含DESC或INVISIBLE;目标库执行相同命令,对比输出是否缺失对应关键词 - 兼容性修复:建索引时显式去掉不可识别语法,例如改用
ASC(默认可省略),或移除INVISIBLE;Navicat 15 对纯 ASC + VISIBLE 索引识别最稳定 - 注意:即使你勾选了“Compare index comments”或“Compare index type”,Navicat 15 仍不解析排序方向和可见性,该选项无效
同步后联合索引字段顺序错乱或类型被强制转换
Navicat 15 在生成 ALTER TABLE ... ADD INDEX 语句时,对联合索引字段顺序的还原能力弱,尤其当字段类型存在隐式转换(如 VARCHAR(191) vs VARCHAR(255))或字符集不同(utf8mb4_0900_as_cs vs utf8mb4_unicode_ci)时,它可能直接丢弃后缀、合并字段或错误降级。
- 常见表现:源索引为
(email VARCHAR(255), tenant_id BIGINT),同步后变成(email, tenant_id)(丢失长度/类型),甚至被拆成两个单列索引 - 必须核对的三处:① 源表
SHOW CREATE TABLE中索引定义;② Navicat 预览窗口中“Difference”标签页里显示的 DDL;③ 同步完成后目标表的实际SHOW CREATE TABLE - 安全做法:取消勾选“Synchronize indexes”选项,改为在“Advanced”→“DDL Options”中关闭“Export indexes”,全部索引由 DBA 手动执行 SQL 创建,确保字段顺序与类型零误差
为什么“强制刷新元数据”也解决不了联合索引识别问题
点击右键 → “Refresh Connection” 或按 F5 只更新表名、列名、主键等顶层结构,不会重新扫描 INFORMATION_SCHEMA.STATISTICS 中的索引字段序列。Navicat 15 的元数据缓存是分层的,索引字段级信息属于“惰性加载”,仅在首次连接或执行结构同步向导时读取一次。
- 真正有效的刷新动作只有两种:① 关闭并重新打开该连接;② 在结构同步向导 Step 1 点击“Options”→ 勾选“Force refresh metadata before comparing”(该选项仅对本次同步生效)
- 但即使强制刷新,Navicat 15 的底层驱动仍无法修正其对多列索引的解析逻辑缺陷——它读到了所有行,但没把它们拼成一个索引对象
- 如果你依赖自动化脚本调用 Navicat CLI(如
navigator.exe /synchronize),它默认不启用元数据强制刷新,必须加参数/refresh,否则永远用旧缓存
联合索引在 Navicat 15 结构同步中不是“偶尔失灵”,而是设计层面的识别盲区。它不报错、不警告、不提示,只是静默跳过——最容易被忽略的,是你以为它“比对完了”,其实它根本没看见。


















