2012-02-13 1 views
0

Я хочу перебрать большую таблицу, которая не подходит в памяти.Столбец в Perl

В Java я могу использовать курсор и загружать содержимое по мере необходимости, а не переполнять память. Как я делаю то же самое с Perl?

База данных, которую я использую, - PostgreSQL и DBI.

+1

В какой базе данных? Какой модуль perl? Какой код? –

+0

@BrianRoach Извините, я новичок в Perl. PostgreSQL и DBI. –

ответ

3

Я использовал курсор PostgreSQL из базы данных PostgreSQL.

my $sql = "SOME QUERY HERE"; 
$dbh->do("DECLARE csr CURSOR WITH HOLD FOR $sql"); 
my $sth = $dbh->prepare("fetch 100 from csr"); 
$sth->execute; 

while(my $ref = $sth->fetchrow_hashref()) {  
    //... - processing here 
    if ($count % 100 == 0){    
     $sth->execute; 
    } 
} 
3

Просто используйте курсор базы данных в PostgreSQL. Пример из manual:

BEGIN WORK; 

-- Set up a cursor: 
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films; 

-- Fetch the first 5 rows in the cursor liahona: 
FETCH FORWARD 5 FROM liahona; 

code |   title   | did | date_prod | kind | len 
-------+-------------------------+-----+------------+----------+------- 
BL101 | The Third Man   | 101 | 1949-12-23 | Drama | 01:44 
BL102 | The African Queen  | 101 | 1951-08-11 | Romantic | 01:43 
JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25 
P_301 | Vertigo     | 103 | 1958-11-14 | Action | 02:08 
P_302 | Becket     | 103 | 1964-02-03 | Drama | 02:28 

-- Fetch the previous row: 
FETCH PRIOR FROM liahona; 

code | title | did | date_prod | kind | len 
-------+---------+-----+------------+--------+------- 
P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 

-- Close the cursor and end the transaction: 
CLOSE liahona; 
COMMIT WORK; 
0

Посмотрите на DBD :: Pg docs для примера.

Использование функции DBI fetchrow_ * в цикле while() для меньшего распределения памяти, избегайте fetchall_ *.

Другие параметры базы данных, связанные с использованием памяти:

  • LongReadLen - максимальная длина 'длинных' полей типа (LONG, BLOB, CLOB, памятка и т.д.)
  • RowCacheSize (не используется в DBD: : Pg) - подсказка к драйверу, указывающая размер кеша локальной строки, который приложение должно использовать драйвер для будущих операторов «SELECT».
1

Что случилось с:

my $s = $h->prepare(select ...); 
$s->execute; 
while(my $row = $fetchrow_arrayref) { 
    ; # do something 
} 
+0

Результат запроса перейдет в память. Если результат больше памяти, есть SWAP и медленный. –

+0

Не с точки зрения DBI это не так. Это выбирает одну строку за раз из DBD. Если DBD решает вернуть более одной строки за раз, что является другой проблемой, и я ожидаю чего-то в DBD или клиентской библиотеке, это зависит от того, чтобы вы могли изменить это поведение. – bohica

+2

Сам libpq всегда будет накапливать весь набор результатов в память: в DBI нет возможности обойти его без использования курсоров – araqnid

 Смежные вопросы

  • Нет связанных вопросов^_^