2011-11-23 73 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

你在這裏怎麼樣?添加代碼來回答。 –

相關問題