navicat 数据同步的 where 条件必须写在「表映射」步骤中每张表的「设置筛选条件」里并勾选「仅同步满足条件的记录」,否则即使选择增量模式也会全量同步;该条件在拉取源数据前静态预执行,填错位置(如高级选项)或未勾选将导致失效。

为什么“WHERE 条件必须写在表映射里,别去高级选项找”
Navicat 17 的数据同步过滤逻辑是静态预执行的:它只在「表映射」步骤中读取你填入的 WHERE 表达式,并在拉取源数据前就完成筛选。这个输入框藏在每张表右侧的 … → 「设置筛选条件」里,且必须勾选「仅同步满足条件的记录」——该选项默认关闭,不勾等于白写。
常见错误现象包括:预览显示 Insert 行数远超预期、目标库多出大量旧数据、日志里反复出现重复主键冲突。根本原因几乎全是漏掉这一步,或误把条件填在「高级选项」→「同步选项」或「字段映射」页签中,那些位置 Navicat 完全不解析 SQL。
实操建议:
- 先在目标库查询窗口里执行你写的
WHERE条件(如SELECT * FROM orders WHERE created_at > '2026-09-04 00:00:00'),确认返回结果符合预期 - 复制整条条件(不含
SELECT或分号),粘贴进「设置筛选条件」框 - 务必检查字段名是否带空格或关键字:MySQL 用反引号包裹(如
`created at`),PostgreSQL 用双引号(如"updated_at")
用主键范围做分段同步:id > 10000 AND id
基于主键分段是最可控的增量方式,但前提是主键单调递增、无归档重用、类型一致。Navicat 不会自动帮你补全边界,所有范围都得手动写死。
典型风险点:
-
id BETWEEN 10000 AND 15000看似简洁,但某些数据库(如早期 MySQL)对BETWEEN边界处理有隐式类型转换,导致漏数据 - 若源表主键是
BIGINT,而目标表是INT,超出范围的值会被截断,同步时可能静默失败或报错 - 用
id > 10000单边条件虽安全,但需确保每次起始值严格大于上一批最大id,否则重复;建议同步完成后查源表MAX(id)记录为下一次起点
推荐写法:id > 10000 AND id ,显式、可预测、兼容性好。注意:不要写 <code>id >= 10001,因为归档操作可能导致 ID 不连续,> 比 >= 更容错。
时间字段分段失效的五个真实原因
用 created_at > '2026-09-04' 分段最常用,也最容易“看起来没同步”。问题往往不出在 SQL 语法,而在底层数据状态。
常见失效场景:
- 字段值全为
NULL:Navicat 过滤时跳过这些行,不报错也不计入统计 - 应用写入 UTC 时间,但数据库服务器时区设为
Asia/Shanghai:你填的'2026-09-04 00:00:00'被解释为东八区时间,实际比 UTC 晚 8 小时,条件永远不成立 - 字段类型是
VARCHAR存时间字符串(如'2026-09-04 10:20:30'):无法参与日期运算,>判断恒为 false - MySQL 5.6 之前
TIMESTAMP无毫秒精度:若应用写入'2026-09-04 10:20:30.123',入库后变成'2026-09-04 10:20:30',刚好卡在边界外 - 字段名大小写不一致:PostgreSQL 中
created_at和CREATED_AT是两个字段,写错一个就查不到
跨库分段同步时怎么避免建表失败或主键冲突
Oracle → MySQL 或 SQL Server → PostgreSQL 这类跨库迁移,分段同步不只是数据搬运,还涉及对象存在性校验和主键策略对齐。
关键动作:
- 先在目标库查已存在表:
SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'target_db',把结果整理成列表 - 在源库 SQL 过滤中排除这些表:
table_name NOT IN ('orders', 'users', ...),粘贴进 Navicat「高级模式」→「表过滤」 - 若主键是自增整型,确认两边初始值不重叠:比如 Oracle 用
1, 3, 5...(奇数段),MySQL 用2, 4, 6...(偶数段),否则分段同步时必然触发Duplicate entry - 禁用「同步不存在的对象」开关:否则即使你排除了某张表,只要目标库没它,Navicat 仍会重建,破坏分段意图
真正麻烦的不是写条件,而是验证条件生效——每次同步后,务必右键日志 → 「查看同步语句」,确认生成的 SQL 里没有被排除的表,也没有全表扫描的痕迹。











