使用SQL*Loader加载1GB文本文件耗时过长,如何优化加载速度?
嘿,我来帮你搞定sqlldr加载慢的问题!针对你1GB的文本文件和现有的ctl配置,这里有几个亲测有效的优化技巧,能大幅缩短加载时间:
开启直接路径加载(Direct Path Load)
默认情况下SQL*Loader用的是常规路径加载,会走Oracle的SQL解析引擎,还会逐个检查约束、触发触发器,对于大文件来说效率极低。直接路径加载会跳过这些环节,直接把数据写入数据块,速度能提升好几倍。
你可以在ctl文件里添加direct=true,修改后的ctl代码如下:load data infile "D:\file1.txt" into table LDR direct=true fields terminated by "," ( name, value )或者在执行sqlldr命令时加上
direct=y参数:sqlldr your_username/your_password@your_db control=your.ctl direct=y。
注意:直接路径有一些限制,比如表不能有触发器、不能有启用的唯一性主键约束(如果有的话,可以先禁用,加载完成后再重新启用)。增大读取缓冲区(Read Buffer)
默认的读取缓冲区大小可能太小,导致SQL*Loader频繁进行磁盘IO操作。你可以通过readsize参数调大缓冲区,比如设置为30MB(根据你的服务器内存情况调整,不要超过可用内存):load data infile "D:\file1.txt" "readsize 31457280" into table LDR direct=true fields terminated by "," ( name, value )临时禁用约束和触发器
加载过程中,Oracle会逐一校验表的约束(比如非空、唯一、外键)并执行触发器,这会严重拖慢加载速度。如果你的数据是干净的(没有不符合约束的内容),可以先禁用这些,加载完成后再重新启用:-- 禁用所有约束 ALTER TABLE LDR DISABLE CONSTRAINT ALL; -- 禁用所有触发器 ALTER TABLE LDR DISABLE ALL TRIGGERS; -- 执行SQL*Loader加载 -- 加载完成后重新启用 ALTER TABLE LDR ENABLE CONSTRAINT ALL; ALTER TABLE LDR ENABLE ALL TRIGGERS;并行加载
如果你的Oracle版本支持,且服务器有多核CPU,可以开启并行加载。在ctl文件里添加parallel=true,或者命令行加parallel=y,配合直接路径使用效果更好:load data infile "D:\file1.txt" into table LDR direct=true parallel=true fields terminated by "," ( name, value )另外,你也可以把1GB的大文件拆分成多个小文件(比如每个200MB),然后同时启动多个sqlldr进程分别加载这些文件,充分利用多核CPU的优势。
调整绑定数组大小(Bind Array)
绑定数组决定了SQL*Loader每次提交到数据库的行数,增大这个值可以减少提交次数,提升效率。比如设置为64MB:load data infile "D:\file1.txt" into table LDR direct=true bindsize=67108864 fields terminated by "," ( name, value )这个值需要根据你的服务器内存情况调整,避免内存不足。
使用本地磁盘加载
如果你的文本文件存放在网络共享盘上,建议先把它复制到Oracle服务器本地的磁盘上。网络IO的速度远低于本地磁盘IO,本地加载能显著提升速度。
内容的提问来源于stack exchange,提问作者Niklaus

