2011-11-23 36 views
1

所有,Perl中的Win32 :: OLE生成Access数据库

[说明]:我从平面文件,并生成列表中读取并加载Access数据库。 Windows XP,Perl 5.8.8,并且无法访问默认安装以外的其他模块。

[问题]:性能,性能,性能。加载所有数据需要大约20分钟的时间。我假设可能有更好的方法来加载数据,而不是添加更新&更新。

[逻辑]:没有张贴我的很多变革,在这里的附加逻辑是什么,我尝试:

  1. 打开文件X
  2. 逐行读取文件的0 X
  3. 射流>从步骤2的字符串中执行一条Create语句
  4. 在行1 -n中读取创建制表符分隔字符串并存储到数组中
  5. 打开记录集从表名
  6. 在阵列荷兰国际集团选择*每个项目
    1. recordset->的AddNew
    2. 分裂基于的标签
      1. 对在分割的每个项目的项目
        1. RS-> Fields- >物品(POS) - > {价值} = ITEM_VALUE
    3. recordset->更新

谢谢。

+0

在20分钟内装载了多少行?每行有多少列(字段)?输入文件总共有多大字节?你是否在加载时创建索引? –

回答

2

缓慢加载的一个问题是在每次更新时都进行提交。确保自动提交关闭,并且每1000行或者其他操作一次。如果它不是一个巨大的负载,不要做它们。另外,请勿在加载过程中创建索引,然后再创建索引。

此外,我不确定OLE是如何做到这一点的最佳方式。我一直使用DBI和Win32 :: ODBC加载Access数据库。速度非常快。

根据要求,这里是样本加载程序,在WinXP,Access 2003,ActiveState Perl 5.8.8上每分钟做了大约100k条记录。

use strict; 
use warnings; 

use Win32::ODBC; 

$| = 1; 

my $dsn = "LinkManagerTest"; 
my $db = new Win32::ODBC($dsn) 
    or die "Connect to database $dsn failed: " . Win32::ODBC::Error(); 

my $rows_added = 0; 
my $error_code; 

while (<>) { 
    chomp; 

    print STDERR "."  unless $. % 100; 
    print STDERR " $.\n" unless $. % 5000; 

    my ($source, $source_link, $url, $site_name) = split /\t/; 

    my $insert = qq{ 
     insert into Links (
      URL, 
      SiteName, 
      Source, 
      SourceLink 
     ) 
     values (
      '$url', 
      '$site_name', 
      '$source', 
      '$source_link' 
     ) 
    }; 

    $error_code = $db->Sql($insert); 

    if ($error_code) { 
     print "\nSQL update failed on line $. with error code $error_code\n"; 
     print "SQL statement:\n$insert\n\n"; 
     print "Error:\n" . $db->Error() . "\n\n"; 
    } 
    else { 
     $rows_added++; 
    } 

    $db->Transact('SQL_COMMIT') unless $. % 1000; 
} 

$db->Transact('SQL_COMMIT'); 
$db->Close(); 

print "\n"; 
print "Lines Read: $.\n"; 
print "Rows Added: $rows_added\n"; 

exit 0; 
+0

负载比访问数据库更大。我相信我正在加载大约30万行。你可以给我一个你的dbi代码样本吗? – XanderLynn

+0

你在这里怎么样?添加代码来回答。 –

相关问题