2009-01-28 33 views
53

Necesito realizar una consulta 2.5 millones de veces. Esta consulta genera algunas filas que necesito para AVG(column) y luego usar esta AVG para filtrar la tabla de todos los valores por debajo del promedio. Entonces necesito INSERT estos resultados filtrados en una tabla.Tablas temporales de PostgreSQL

La única manera de hacer tal cosa con una eficiencia razonable, parece ser mediante la creación de un TEMPORARY TABLE para cada cadena de python-postmaster de consulta. Solo espero que estos TEMPORARY TABLE s no se conserven en el disco duro (en absoluto) y que permanezcan en la memoria (RAM), a menos que estén sin memoria de trabajo, por supuesto.

me gustaría saber si una tabla temporal incurrirá en las escrituras en disco (que interferirían con los insertos, es decir lentas para todo el proceso hacia abajo)

+5

¿Y cuál es su pregunta aquí, exactamente? – Tim

+0

Jajaja, lo siento. Quiero saber si una TABLA TEMPORAL incurrirá en escrituras en el disco (lo que interferiría con los INSERTOS, es decir, retrasaría todo el proceso). ¡Gracias! –

+0

Esto es aparentemente un tanto controvertido. Mira este hilo fuera http://www.nabble.com/Create-and-drop-temp-table-in-8.3.4-td20347767.html – Xedecimal

Respuesta

85

Tenga en cuenta que, en Postgres, el comportamiento predeterminado para las tablas temporales es que no se eliminan automáticamente, y los datos se mantienen en la confirmación. Ver ON COMMIT.

tabla temporal son, sin embargo, dropped at the end of a database session:

tablas temporales se eliminan automáticamente al final de una sesión, o opcionalmente al final de la transacción actual.

hay múltiples consideraciones que hay que tener en cuenta:

  • Si desea una tabla temporal al final de una transacción, crear explícitamente DROP con la sintaxis CREATE TEMPORARY TABLE ... ON COMMIT DROP.
  • En presencia del agrupamiento de conexiones, una sesión de base de datos puede abarcar varias sesiones de cliente; para evitar conflictos en CREATE, debe eliminar sus tablas temporales, ya sea antes de devolver una conexión al grupo (por ejemplo, haciendo todo dentro de una transacción y usando la sintaxis de creación ON COMMIT DROP), o según sea necesario (por precediendo cualquier declaración CREATE TEMPORARY TABLE con un DROP TABLE IF EXISTS correspondiente, que tiene la ventaja de que también funciona fuera de transacciones, por ejemplo, si la conexión se usa en modo autocompromiso).
  • Mientras la tabla temporal está en uso, ¿cuánto de ella cabe en la memoria? antes de desbordar en el disco? Vea la opción temp_buffers en postgresql.conf
  • ¿Algo más de lo que debería preocuparme cuando trabajo a menudo con tablas temporales? Se recomienda una aspiradora después de haber eliminado las tablas temporales, para limpiar las tuplas muertas del catálogo. Postgres vaciará automáticamente cada 3 minutos más o menos cuando utilice la configuración predeterminada (auto_vacuum).

también, sin relación con su pregunta (pero posiblemente relacionada con su proyecto): tenga en cuenta que, si tiene que ejecutar consultas en una tabla temporal después de haber llenado ella, entonces es una buena idea para crear índices apropiados y emitir un ANALYZE en la tabla temporal en la pregunta después de ha terminado de insertar en él. De forma predeterminada, el optimizador basado en el costo supondrá que una tabla temp recientemente creada tiene ~ 1000 filas y esto puede dar como resultado un bajo rendimiento si la tabla temporal contiene realmente millones de filas.

+0

cosas buenas. Gracias. De hecho, solo utilicé una tabla temporal ya que necesitaba ejecutar dos SELECT diferentes sobre ella (por lo que un análisis no valdría la pena, me imagino). Proporcioné las operaciones con muchos temp_buffers, sin embargo, dado que muchas tablas de TEMP se creaban y descartaban por muchos hilos de python, ... –

+0

postgres estaba consumiendo más y más RAM a medida que el script hacía su trabajo. Descubrí que al limitar la cantidad de subprocesos de python (que se ejecutan en una computadora cliente) a un poco más que la cantidad de núcleos de CPU, se obtenían los mejores (más eficientes y efectivos) tiempos de ejecución. Otra vez para ti, sabiduría Vlad. –

+1

Incluso si solo SELECCIONA en la tabla temporal dos veces, invertir unos milisegundos en una creación de índice + ANALIZAR cada vez que crea la tabla temporal podría ahorrarle toneladas cuando/si une otras tablas con la tabla temporal - ponga las consultas manualmente en PgAdminIII y use la función "Query/Explain (F7)". – vladr

12

Las tablas temporales proporcionan sólo una garantía - se dejan caer al final de La sesión. Para una mesa pequeña, probablemente tenga la mayoría de sus datos en la tienda de respaldo. Para una tabla grande, garantizo que los datos se eliminarán periódicamente en el disco ya que el motor de la base de datos necesita más espacio de trabajo para otras solicitudes.

EDIT: Si necesita absolutamente tablas temporales solo de RAM, puede crear un espacio de tabla para su base de datos en un disco RAM (/ dev/shm funciona). Esto reduce la cantidad de IO de disco, pero tenga en cuenta que actualmente no es posible hacer esto sin una escritura de disco físico; el motor DB vaciará la lista de la tabla a un almacenamiento estable cuando cree la tabla temporal.

Cuestiones relacionadas