2010-02-23 11 views
5

Piszę niektóre skrypty Perla, aby manipulować dużymi kwotami (w sumie około 42 milionów wierszy, ale nie zostanie to zrobione jednym trafieniem) danych w dwóch bazach danych PostgreSQL.Jaka jest różnica w wydajności między fetchall_hashref i fetchall_arrayref DBI?

Dla niektórych z moich zapytań warto użyć fetchall_hashref, ponieważ mam klucze syntetyczne. Jednak w innych przypadkach będę używał tablicy trzech kolumn jako unikalnego klucza.

To sprawiło, że zastanawiałem się nad różnicami w wydajności między fetchall_arrayref i fetchall_hashref. Wiem, że w obu przypadkach wszystko idzie do pamięci, więc wybranie kilku GB danych prawdopodobnie nie jest dobrym pomysłem, ale poza tym wydaje się, że w dokumentacji jest bardzo mało wskazówek, jeśli chodzi o wydajność.

Moje przegrupowanie go nie powiodło się, więc jeśli ktoś może wskazać mi kierunek ogólnych badań wydajności, będę wdzięczny.

(Wiem, że mogę to sprawdzić samodzielnie, ale niestety dla celów programistów nie mam dostępu do maszyny, która ma identyczny sprzęt do produkcji, dlatego szukam ogólnych wskazówek, a nawet najlepszych praktyk).

Odpowiedz

3

Pierwsze pytanie brzmi: czy naprawdę trzeba najpierw użyć fetchall. Jeśli nie potrzebujesz wszystkich 42 milionów wierszy w pamięci jednocześnie, nie czytaj ich wszystkich naraz! bind_columns i fetchrow_arrayref są na ogół drogą, o której mowa, jak już wskazano.

Zakładając, że fetchall naprawdę jest potrzebne, moja intuicja jest gut że fetchall_arrayref będzie nieznacznie szybciej, ponieważ tablica jest prostsza struktura danych i nie trzeba obliczyć hashe wstawionej kluczy, ale oszczędności czasu byłoby przerywane przez czasy odczytu bazy danych, więc jest mało prawdopodobne, aby były znaczące.

Wymagania dotyczące pamięci to jednak zupełnie inna sprawa. Struktura zwrócona przez fetchall_hashref jest hash z id => row, przy czym każdy wiersz jest reprezentowany jako mieszanie field name => field value. Jeśli uzyskasz 42 miliony wierszy, oznacza to, że lista nazw pól powtarza się w każdym z 42 milionów zestawów kluczy hashowych ... To będzie wymagać dużo więcej pamięci do przechowywania niż tablica tablic zwracanych przez fetchall_arrayref. (Chyba że DBI robi trochę magii z tie, aby zoptymalizować strukturę fetchall_hashref, przypuszczam.)

+0

Dziękuję za to - jak na pewno wrócę za pomocą fetchall ... i ponownie rozważyć hash. – azp74

5

Większość opcji wyboru między metodami pobierania zależy od formatu, w jakim dane mają się znaleźć, a także od tego, ile pracy ma dla ciebie zrobić DBI.

Moim wspomnieniem jest to, że iteracja za pomocą fetchrow_arrayref i używanie bind_columns jest najszybszym (najmniejszym obciążeniem DBI) sposobem odczytywania zwróconych danych.

+1

To pasuje do mojego własnego zrozumienia. – fennec

+1

... i z dokumentami. Per http://search.cpan.org/~timb/DBI-1.609/DBI.pm#fetchrow_arrayref "Jest to najszybszy sposób pobierania danych, szczególnie jeśli jest używany z $ sth-> bind_columns." –

+0

Należy zauważyć, że redaktor zawęził fokus tytułu tego pytania. Dla mnie wcześniej niejednoznaczne było to, czy cała kwestia miała tak wąski zakres, i wybieram bardziej ogólną odpowiedź. – ysth