¿Por qué la caída de rendimiento de PostgreSQL consulta con el tiempo, pero restaurada cuando la reconstrucción de índice

StackOverflow https://stackoverflow.com/questions/2392982

Pregunta

De acuerdo con esta página en el manual, indexes don't need to be maintained. Sin embargo, nos estamos quedando con una mesa de PostgreSQL que tiene una tasa continua de updates, deletes y inserts que con el tiempo (unos días) ve una degradación significativa consulta. Si borramos y volver a crear el índice, consulta de rendimiento se restaura.

Estamos utilizando salir de la configuración del cuadro.
La mesa en nuestra prueba está empezando a cabo vacía y crece hasta medio millón de filas. Tiene una fila bastante grande (un montón de campos de texto).

Estamos searching based of an index, not the primary key (He confirmado se está utilizando el índice, al menos en condiciones normales)

La tabla se está utilizando como un almacén persistente para un solo proceso. El uso de PostgreSQL en Windows con un cliente Java.

Estoy dispuesto a renunciar a insert and update performance para mantener el rendimiento de las consultas.

Estamos pensando en rediseñar la aplicación para que los datos se propaga a través de varias tablas dinámicas de una manera que nos permite soltar y volver a generar índices periódicamente sin afectar a la aplicación. Sin embargo, como siempre, hay una escasez de tiempo para conseguir que esto funcione y sospecho que nos falta algo básico en nuestra configuración o uso.

Hemos considerado forcing vacuuming y rebuild to run at certain times, pero sospecho que la locking period for such an action would cause our query to block. Esto puede ser una opción, pero hay algunos en tiempo real (ventanas de 3-5 segundos) implicaciones que requieren otros cambios en nuestro código.

Información adicional: Tabla y el índice

CREATE TABLE icl_contacts
(
  id bigint NOT NULL,
  campaignfqname character varying(255) NOT NULL,
  currentstate character(16) NOT NULL,
  xmlscheduledtime character(23) NOT NULL,
...
25 or so other fields.  Most of them fixed or varying character fiel  
...
  CONSTRAINT icl_contacts_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE icl_contacts OWNER TO postgres;

CREATE INDEX icl_contacts_idx
  ON icl_contacts
  USING btree
  (xmlscheduledtime, currentstate, campaignfqname);

Analizar:

Limit  (cost=0.00..3792.10 rows=750 width=32) (actual time=48.922..59.601 rows=750 loops=1)
  ->  Index Scan using icl_contacts_idx on icl_contacts  (cost=0.00..934580.47 rows=184841 width=32) (actual time=48.909..55.961 rows=750 loops=1)
        Index Cond: ((xmlscheduledtime < '2010-05-20T13:00:00.000'::bpchar) AND (currentstate = 'SCHEDULED'::bpchar) AND ((campaignfqname)::text = '.main.ee45692a-6113-43cb-9257-7b6bf65f0c3e'::text))

Y, sí, soy consciente de que hay una variedad de cosas we could do to normalize and improve the design of this table. Algunas de estas opciones pueden estar disponibles para nosotros.

Mi enfoque en esta pregunta es: sobre how PostgresQL is managing the index and query over time (understand why, not just fix) comprensión. Si se llegara a hacer más o significativamente rediseñado, no habría una gran cantidad de cambios.

¿Fue útil?

Solución

vacío auto debe hacer el truco, siempre lo configuró para su rendimiento deseado.

Notas: Vacío total: este reconstruirá estadísticas de la tabla y cargas a la reposición del espacio en disco. Se bloquea la tabla entera.

vacío: esto va a reconstruir las estadísticas de tabla y recuperar algo de espacio en disco. Se puede ejecutar en paralelo con el sistema de producción, sino que genera una gran cantidad de IO que puede afectar al rendimiento.

ANALIZAR: esto va a reconstruir consulta las estadísticas planificador. Esto es provocado por el vacío, sino que se puede ejecutar por sí misma.

notas detalladas encontrar aquí

Otros consejos

En cuanto a rendimiento, el uso de cadenas para almacenar el tiempo y el estado de información es absolutamente un cuello de botella. En primer lugar, los índices de los textos son extremadamente ineficientes, la comparación de dos veces en el mismo día las necesidades al menos 11 comparación (en el formato que se utiliza), sin embargo, utilizando el tipo de tiempo que puede reducirse a una simple comparación. Esto también afecta al tamaño del índice, y un índice tan grande es difícil de buscar más, y el PP no va a mantener en la memoria. Las mismas consideraciones se aplican a la columna de estado. Si representa un pequeño conjunto de estados, se debe utilizar números enteros asignados a los estados, esto reducirá los nodos del índice - y el tamaño del índice en consecuencia. Por otra parte, este índice será inútil incluso utilizando theese tipos incorporados, si no se especifica el tiempo real en su consulta.

Esto huele índice de hinchazón a mí. I'l que se refieren a esta página

http://www.postgresql.org/docs/8.3/ estática / rutina reindex.html

que dice en la parte inferior:

  

Además, para los índices de árbol B una   índice construido recién es algo   más rápido que el acceso de uno que tiene   han actualizado muchas veces, porque   lógicamente páginas adyacentes son generalmente   también físicamente adyacentes en un recién   Índice de edificio. (Esta consideración hace   no se aplican actualmente a los no-B-tree   índices.) podría ser útil para   indexar periódicamente sólo para mejorar   la velocidad de acceso.

Lo cual no parecen estar en conflicto con la página que se le haga referencia diciendo que los índices "no requieren mantenimiento o puesta a punto".

¿Usted ha intentado "crear el índice al mismo tiempo"?

Es la '2010-05-20T13: 00: 00.000'? Xmlscheduledtime valor que está siendo comparado con, parte del SQL, o se suministra como un parámetro

Cuando la planificación de cómo ejecutar la consulta, diciendo que un campo debe ser inferior a un parámetro suministrado con un valor hasta ahora desconocido no da PostgreSQL mucho para seguir adelante. No se sabe si eso va coinciden casi todas las filas, o casi ninguna de las filas.

cómo las estadísticas usos planificador ayuda enormemente cuando se trata de averiguar por qué su base de datos está utilizando los planes se encuentra.

Usted puede obtener seleccionar mejor rendimiento cambiando el orden de los campos en los que el índice complejo, o la creación de un nuevo índice, con los campos ordenados (campaignfqname, currentState, xmlscheduledtime), ya que entonces el índice le llevará directamente al nombre fq campaña y el estado actual que está interesado, y el índice de exploración en todo el rango xmlscheduledtime todo será filas que está buscando.

Esto es un caso de libro. Debería configurar autovacuum a ser mucho más agresivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top