2010-02-23 8 views
5

Estoy escribiendo algunas secuencias de comandos Perl para manipular grandes cantidades (en total alrededor de 42 millones de filas, pero no se hará en un solo golpe) de datos en dos bases de datos PostgreSQL.¿Cuál es la diferencia de rendimiento entre fetchall_hashref y fetchall_arrayref de DBI?

Para algunas de mis consultas, tiene sentido usar fetchall_hashref porque tengo claves sintéticas. Sin embargo, en otras instancias, voy a utilizar una matriz de tres columnas como clave única.

Esto me tiene preguntando sobre las diferencias de rendimiento entre fetchall_arrayref y fetchall_hashref. Sé que en ambos casos todo está entrando en la memoria, por lo que seleccionar varios GB de datos probablemente no es una buena idea, pero aparte de eso, parece que hay muy poca guía en la documentación cuando se trata de rendimiento.

Mi google no ha tenido éxito, así que si alguien puede indicarme algunos estudios generales de rendimiento, le agradecería.

(Sé que podría comparar esto yo mismo, pero desafortunadamente para fines de desarrollo no tengo acceso a una máquina que tiene hardware idéntico a la producción, es por eso que estoy buscando pautas generales o incluso las mejores prácticas).

Respuesta

3

La primera pregunta es si realmente necesita usar un fetchall en primer lugar. Si no necesita las 42 millones de filas en la memoria a la vez, ¡entonces no las lea todas a la vez! bind_columns y fetchrow_arrayref son generalmente el camino a seguir siempre que sea posible, como ya se ha señalado.

Suponiendo que fetchall realmente se necesita, mi intuición de la tripa es que fetchall_arrayref habrá marginalmente más rápido, ya que una matriz es una estructura de datos simple y no necesita calcular los hashes de las claves insertadas, pero el ahorro de tiempo sería empequeñecido por los tiempos de lectura de la base de datos, por lo que es poco probable que sea significativo.

Los requisitos de memoria son otro asunto completamente diferente. La estructura devuelta por fetchall_hashref es un hash de id => row, con cada fila representada como un hash de field name => field value. Si obtienes 42 millones de filas, eso significa que tu lista de nombres de campo se repite en cada uno de los 42 millones de conjuntos de claves hash ... Eso requerirá mucho más memoria para almacenar que la matriz de matrices devueltas por fetchall_arrayref. (A menos que DBI esté haciendo magia con tie para optimizar la estructura fetchall_hashref, supongo.)

+0

Gracias por esto, ya que definitivamente volveré a visitar usando fetchall ... y reconsiderar el hash. – azp74

5

La mayoría de las opciones entre los métodos de búsqueda dependen del formato en el que desee que termine la información y de la cantidad de trabajo que desea que DBI haga por usted.

Mi recuerdo es que iterar con fetchrow_arrayref y usar bind_columns es la manera más rápida (sobrecarga de DBI) para leer los datos devueltos.

+1

Esto coincide con mi propio entendimiento. – fennec

+1

... y con los documentos. Por http://search.cpan.org/~timb/DBI-1.609/DBI.pm#fetchrow_arrayref "Esta es la forma más rápida de recuperar datos, particularmente si se usa con $ sth-> bind_columns". –

+0

Tenga en cuenta que un editor redujo el foco del título de esta pregunta. Para mí, era ambiguo hasta entonces si toda la pregunta tenía ese enfoque limitado, y elijo responder de manera más general. – ysth

Cuestiones relacionadas