有没有人尝试在Perl程序中使用DB2导入?
我的应用程序插入了1000万行,显然是使用DBI进行连接并逐行进行插入需要永久。
命令行中的DB2导入/加载效果很好,但有一种更好的方法,而不是从Perl程序调用系统调用来调用:
use IPC::System::Simple qw( systemx );
use autodie;
systemx( "db2 connect ..." );
systemx( "db2 import ..." );
etc?
谢谢!
答案 0 :(得分:1)
我没有任何DB2经验。根据我对Oracle和MySQL的经验,我希望逐行更新最慢,多行插入更快(如果DB2和DBI支持),并且供应商提供的批量工具最快。运行一些基准来确定。
答案 1 :(得分:1)
使用DBI执行此操作的最快方法是准备sql insert语句,然后多次执行它。 DBIx :: Classes populate方法在内部执行此操作。
答案 2 :(得分:1)
我可以想到两种基本方法。
选项1.通过perl DBI导入。使用$ dbh上的prepare方法准备insert语句。关闭自动提交(通常在connect()
),然后发疯。出于内存原因,您可能经常需要COMMIT
(可能每1000次插入)。这是权衡:您提交的频率越高,您使用的内存越少,但您将面对磁盘的同步开销越多。默认情况下,启用自动提交后,您将在每次插入后有效地提交,从而减速。
选项2.您可以针对具有连接,导入等命令的DDL文件调用DB2 CLP。这减少了产生多个进程的开销。
就个人而言,我先尝试#1。
答案 3 :(得分:1)
我确实遇到了你似乎遇到的问题。似乎在某些系统上,您必须在导入之前显式执行DB2 Connect。
事实上,当我在import语句之前有一个DB2 Connect字符串时,我发现我的脚本表现最为一致,但这可能是系统相关的问题。
建议的解决方案:
我开始时使用如下连接语句。检查此语句是否有效还可以确认您的数据库路径是否有效。
db2 connect to $DB_NAME user $DB_USER using $DB_PASS
我最终将上面的字符串保存为$connnection_starter
,因为您将在多个地方使用它。
然后我按照以下方式拨打了system
电话:
system($con_starter . "; db2 import from $temp_file_path of del commitcount 5000 $insert_update_setting into tablespace.$table_name");
在您的情况下不一定需要commitcount
值(虽然它通常非常适合非常大的导入)但我建议使用它,因为它会导致DB2在导入状态上记录消息如果您通过命令行/ shell运行脚本,则每5000条记录。
错误检查
您可以引入$?
的值以查看导入命令期间是否产生错误,因为如果行为正确,它应该返回0
。
令人讨厌的是,其他返回代码不是很有帮助。我设置了我的导入命令,以便在发生故障时记录确切的语句,以便我可以在以后手动查看它:
if ($? ne 0){
$logger->warn("Failed to import $temp_file_path to table $table_name \nError: $?");
$logger->warn("Exact statement: \t " . $con_starter . "; db2 import from $temp_file_path of del commitcount 5000 $insert_update_setting into tablespace.$table_name");
希望这有帮助!