2010-02-23 5 views
5

J'écris des scripts Perl pour manipuler de grandes quantités (au total environ 42 millions de lignes, mais cela ne sera pas fait en une seule fois) de données dans deux bases de données PostgreSQL.Quelle est la différence de performance entre fetchall_hashref de DBI et fetchall_arrayref?

Pour certaines de mes requêtes, il est logique d'utiliser fetchall_hashref parce que j'ai des clés synthétiques. Cependant, dans d'autres cas, je vais utiliser un tableau de trois colonnes comme clé unique. Cela m'a fait me poser des questions sur les différences de performance entre fetchall_arrayref et fetchall_hashref. Je sais que dans les deux cas, tout va dans la mémoire, donc sélectionner plusieurs Go de données n'est probablement pas une bonne idée, mais à part ça, il semble y avoir très peu de conseils dans la documentation en termes de performances.

Mon googling a échoué, donc si quelqu'un peut me diriger vers des études de performance générale, je serais reconnaissant.

(Je sais que je pourrais le comparer moi-même mais malheureusement pour les besoins de développement je n'ai pas accès à une machine qui a un matériel identique à la production, c'est pourquoi je cherche des directives générales ou même meilleures pratiques).

Répondre

3

Première question est de savoir si vous vraiment besoin d'utiliser un fetchall en premier lieu. Si vous n'avez pas besoin des 42 millions de lignes en même temps, ne les lisez pas toutes en même temps! bind_columns et fetchrow_arrayref sont généralement la voie à suivre autant que possible, comme vous l'avez déjà souligné.

En supposant que fetchall est vraiment nécessaire, mon intuition intestinale est que fetchall_arrayref sera marginalement plus rapide, car un tableau est une structure de données plus simple et n'a pas besoin de calculer hash des clés insérés, mais les économies de temps serait éclipsé par les temps de lecture de la base de données, il est donc peu probable qu'il soit significatif.

Les besoins en mémoire sont cependant entièrement différents. La structure renvoyée par fetchall_hashref est un hachage de id => row, chaque ligne étant représentée comme un hachage de field name => field value. Si vous obtenez 42 millions de lignes, cela signifie que votre liste de noms de champs est répétée dans chacun des 42 millions de jeux de clés de hachage ... Cela nécessitera beaucoup plus de mémoire à stocker que le tableau de tableaux de tableaux retournés par fetchall_arrayref. (À moins que DBI fasse de la magie avec tie pour optimiser la structure fetchall_hashref, je suppose.)

+0

Merci pour cela - comme je vais certainement revoir en utilisant fetchall ... et reconsidérer le hachage. – azp74

5

La plupart des choix entre les méthodes d'extraction dépendent du format dans lequel vous voulez que les données finissent et de la quantité de travail que DBI doit effectuer pour vous. D'après mes souvenirs, itérer avec fetchrow_arrayref et utiliser bind_columns est le moyen le plus rapide (le plus léger de DBI) pour lire les données renvoyées.

+1

Cela correspond à ma propre compréhension. – fennec

+1

... et avec les docs. Per http://search.cpan.org/~timb/DBI-1.609/DBI.pm#fetchrow_arrayref "C'est le moyen le plus rapide pour récupérer des données, en particulier s'il est utilisé avec $ sth-> bind_columns." –

+0

Notez qu'un éditeur a réduit l'accent du titre de cette question. À ce moment-là, il était ambigu de voir si toute la question avait une portée étroite et j'ai choisi de répondre plus généralement. – ysth

Questions connexes