Perl Win32 :: Создание базы данных доступа OLE - PullRequest
1 голос
/ 24 ноября 2011

All

[Описание]: Я читаю из списка простых файлов, генерирую и загружаю базу данных доступа. Windows XP, Perl 5.8.8, и нет доступа к дополнительным модулям за пределами установленного по умолчанию.

[Issue (s)]: Производительность, Производительность, Производительность. Загрузка всех данных занимает около 20 минут. Я предполагаю, что может быть лучший способ загрузить данные, а не добавлять и обновлять.

[Логика]: Я не пытаюсь опубликовать здесь множество моих преобразований и дополнительной логики:

  1. Открыть файл x
  2. чтение строки 0 файла x
  3. jet-> выполнить оператор Create из строки, полученной из шага 2
  4. чтение строк 1 - n создание строки с разделителями табуляции и сохранение в массиве
  5. Открыть набор записей, используя select * from tablename
  6. для каждого элемента в массиве
    1. recordset-> AddNew
    2. разделить элемент на основе вкладки
      1. за каждый элемент в разделении
        1. rs-> Fields-> Item (pos) -> {Value} = item_value
    3. recordset-> Update

Спасибо.

1 Ответ

2 голосов
/ 24 ноября 2011

Одной из проблем при медленной загрузке является фиксация при каждом обновлении.Убедитесь, что автоматические коммиты отключены и делайте один раз каждые 1000 строк или что-то еще.Если это не гигантская нагрузка, не делайте их вообще.Кроме того, не создавайте индексы во время загрузки, создавайте их впоследствии.

Кроме того, я не уверен, что OLE - лучший способ сделать это.Я загружаю базы данных Access все время, используя DBI и Win32 :: ODBC.Идет довольно быстро.

Для каждого запроса, вот пример программы загрузки, выполнял около 100 000 записей в минуту на WinXP, Access 2003, ActiveState Perl 5.8.8.

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...