DB2数据库在数据迁移、批量初始化或备份恢复场景中,经常需要将外部文件的数据写入表。IMPORT和LOAD是DB2提供的两种核心数据移动命令,虽然目标一致,但执行路径完全不同。理解二者的差异,不仅能避免性能瓶颈,还能防止出现表无法访问或约束失效的问题。接下来从底层机制、日志恢复、约束处理、表状态等方面进行对比。

工作机制的根本差异:IMPORT走SQL层,LOAD直接写数据页
IMPORT命令由数据库管理器驱动。它逐行读取输入文件,把每一行数据转换成一条INSERT语句,再交给SQL引擎执行。这意味着每一行都要经历完整的SQL处理流程:语法解析、权限检查、约束验证、触发器调用、索引更新以及事务日志记录。正因为这条链路完整,数据的一致性得到充分保障,但代价是CPU和I/O开销显著增加。当数据量达到百万行级别时,逐行插入会让执行时间成倍增长。
LOAD命令则完全不同。它由独立的db2load工具在数据库外部完成大部分工作,直接读取输入文件、解析格式,并将数据格式化成表空间的页结构后写入磁盘。LOAD不会把每行数据转化成INSERT语句,而是绕过SQL引擎直接操作底层存储。这种页级写入方式省去了大量SQL层处理,速度通常比IMPORT快数倍甚至数十倍。下面的两个命令展示了它们的基本用法,表面上看只有命令名称不同,但底层行为差异巨大。
IMPORT FROM /data/employee.del OF DEL INSERT INTO employee;
LOAD FROM /data/employee.del OF DEL INSERT INTO employee;
日志记录与恢复行为对比
IMPORT在导入过程中会产生完整的事务日志。每一行INSERT操作都会写入redo日志,必要时还会写入undo日志。如果导入中途发生故障,数据库可以基于日志回滚到导入之前的状态,已经提交的部分也受到事务保护。这种特性使IMPORT非常适合对数据可恢复性要求较高的核心表,即使导入失败,也不会留下不一致的数据。
LOAD默认采用最少日志记录策略,甚至在某些模式下不记录数据页变更。因为数据是直接写到表空间容器中的,数据库管理器并没有逐行生成日志。这样虽然大幅提升了导入速度,但也带来一个关键后果:LOAD完成后,如果没有额外的备份或复制副本,仅靠日志无法前滚恢复导入的数据。DB2为此提供了可恢复选项,例如在LOAD命令中使用COPY YES或NONRECOVERABLE参数。指定COPY YES时,LOAD会生成一份数据副本,用于后续恢复;而NONRECOVERABLE表示不保留恢复副本,仅适合导入后立即进行全量备份的场景。
LOAD FROM /data/employee.del OF DEL INSERT INTO employee COPY YES;
LOAD FROM /data/employee.del OF DEL INSERT INTO employee NONRECOVERABLE;
约束、触发器与索引的处理差异
IMPORT按普通INSERT方式写入数据,因此会触发表上定义的BEFORE INSERT和AFTER INSERT触发器,同时也会检查唯一约束、外键约束和检查约束。如果某一行违反约束,IMPORT会依据参数跳过错误行或直接终止。这种方式保证了导入后的数据满足业务规则,对于依赖触发器维护审计字段、自动生成编号等场景非常重要。
LOAD默认不会触发任何触发器,也不会检查绝大多数约束。由于它直接写入数据页,即使数据违反唯一约束或外键约束,也可能暂时进入表中。LOAD完成后,表通常会被置于SET INTEGRITY PENDING状态,表示需要验证完整性。此时必须执行SET INTEGRITY命令,系统才会对已有数据和新导入数据做约束检查,并更新表的完整性状态。否则表仍然不可访问。这一机制虽然增加了后续步骤,但避免了在导入过程中逐行检查约束的巨大开销。
SET INTEGRITY FOR employee IMMEDIATE CHECKED;
索引处理方面,IMPORT插入每一行时都会同步维护索引,LOAD则根据索引类型和选项决定是重建索引还是增量维护。对于大量数据导入,LOAD在建索引上的策略通常更高效,但导入期间索引可能不可用或需要额外时间完成重建。
表状态变化与后续维护
IMPORT完成后,表通常保持正常可访问状态。数据通过事务提交,如果有错误行,通过指定MODIFIED BY选项可以记录到错误文件,但表本身不会进入待处理状态。管理员可以立即对表执行查询、更新等操作。这对在线业务影响较小,适合需要边导入边使用的场景。
LOAD在默认情况下可能使表进入LOAD PENDING或SET INTEGRITY PENDING状态。此时执行SELECT或UPDATE会收到SQL0668N错误。要恢复表可用,需要执行SET INTEGRITY语句或解决加载过程中出现的异常。对于分区表或包含物化查询表的情况,LOAD还可能要求进一步处理。因此选择LOAD意味着必须安排维护窗口,因为导入后不能马上让应用访问表。
性能表现与适用场景建议
从性能角度看,LOAD远快于IMPORT,尤其在处理千万行级别的大文件时差距更加明显。由于LOAD绕过了SQL引擎和日志记录,它的瓶颈主要在磁盘I/O和文件解析速度上。IMPORT由于每一行都产生SQL语句和日志,资源消耗成倍增加。实际测试中,相同服务器和文件条件下,LOAD的导入速度往往是IMPORT的5到20倍。
但性能并不是唯一决策因素。如果表上有复杂的触发器逻辑,或者需要保证导入过程完全可回滚,IMPORT更合适。如果目标表是核心业务表且导入数据量不大,IMPORT的稳定性优势突出。LOAD更适合大批量初始化、数据仓库加载、测试环境数据灌入等场景,但必须提前规划好备份、约束检查和表状态恢复的步骤。
常见误区与注意事项
第一个误区是认为LOAD因为不记录日志就一定不安全。实际上LOAD支持COPY YES和RECOVERABLE选项,能够生成恢复副本,管理员可以在导入前通过备份和归档日志策略来保证可恢复性。第二个误区是认为LOAD可以像IMPORT一样触发触发器,结果导入后业务逻辑没有执行,导致派生字段为空或审计记录缺失。第三个误区是LOAD完成后不执行SET INTEGRITY就立即查询,结果遇到SQL0668N错误,误以为数据损坏。
此外,IMPORT和LOAD对文件格式的支持也有差异。IMPORT支持DEL、ASC、WSF和IXF等多种格式,LOAD则主要针对DEL、ASC和IXF等格式,并提供了更多的格式控制参数。选择命令前应确认输入文件的格式和表结构是否匹配,并测试在会话中设置正确的代码页,避免出现字符转换问题。