2009-09-09 19 views
6

Cajero automático Estoy tratando de aprender a utilizar de manera eficiente los fondos de la base de datos y agradecería recibir algún aporte de expertos. No tengo problemas de rendimiento actualmente. Me gustaría saber, cómo manejaría sus índices con esta consulta:¿Cómo acelerar esta consulta?

SELECT B.event, 
     COALESCE(B.system, C.surname || ' ' || C.forename) AS name, 
     C.label, 
     B.timestamp 
FROM A    
    INNER JOIN B ON A.event=B.event 
    INNER JOIN C ON B.state=C.id 
    LEFT OUTER JOIN D ON B.hur=D.id    
WHERE A.id IN(12,13,14,15,...) 
    ORDER BY B.event, B.timestamp 

A.id, C.id y D.id ya son claves primarias

ACTUALIZACIÓN normalmente pondría ÍNDICE (A.event) e ÍNDICE (B.event, B.timestamp). ¿Es esto correcto? ¿Y qué tal B.event, B.state y B.hur?

+0

Correcto, pero compruebe si se usará B.timestamp en realidad. – Pomyk

+0

¿Qué tan grande es cada una de las tablas, y cuántas filas esperaría que coincidan de una consulta determinada. ¿Qué base de datos estás usando? –

+0

Además, ¿con qué frecuencia se agregan datos a las tablas y con qué frecuencia desea ejecutar la consulta? –

Respuesta

3

reescribir su consulta como esta:

SELECT B.event, 
     COALESCE(B.system, C.surname || ' ' || C.forename) AS name, 
     C.label, 
     B.timestamp 
FROM B    
INNER JOIN 
     C 
ON  C.id = B.state 
LEFT OUTER JOIN 
     D 
ON  D.id = B.hur 
WHERE B.event IN 
     (
     SELECT event 
     FROM A 
     WHERE A.id IN (12, 13, 14, 15) 
     ) 
ORDER BY 
     B.event, B.timestamp 

, y crear un índice compuesto de B (event, timestamp)

2

Puede agregar índices a todo en las cláusulas WHERE y ORDER BY. Es decir, el evento, B.event y B.timestamp.

+1

No agregue índices a ciegas. Ver la respuesta de Lieven. Agregar índices ciegamente puede dañar el rendimiento ya que cada índice debe mantenerse. En algunos casos, como en las mesas pequeñas, esto dolerá, ya que el IO utilizado para mantener podría usarse en otro lugar. A veces, una exploración de tabla completa en una tabla pequeña es mejor que los índices. – jim

+0

Estoy tentado de eliminar mi respuesta; sin embargo, el comentario de Jim es información útil, entonces, ¿debería dejarse la respuesta? – darasd

0
SELECT B.event, B.system, COALESCE(C.surname) || ' ' || COALESCE(C.forename) AS name, C.label, B.timestamp 
FROM A    
INNER JOIN B ON A.event=B.event 
INNER JOIN C ON B.state=C.id 
LEFT OUTER JOIN D ON B.hur=D.id    
WHERE A.event = ANY(:visits) 
ORDER BY B.event, B.timestamp 

También ORDER BY ralentizará las cosas. asegurarse de que estos son indexados:

A.event 
B.event 
B.state 
C.id 
B.timestamp 
3

por lo general toman estos pasos para intentar acelerar mis consultas

  1. analizar el plan de ejecución.
  2. intente crear (cubrir) índices para eliminar escaneos de tabla.
  3. intente crear (cubrir) índices para eliminar escaneos de índice.

cuanto se consulta, usted no iría mal con la creación de índices en

  • A.event
  • B.event
  • B.state
  • B.Hur
+0

Crear índices separados para B.event y B.state no es lo mismo que crear un índice en (B.event, B.state). Es importante diferenciar esto ya que tiene un impacto directo en el rendimiento. – MatBailie

+0

@Dems: si eso no quedó claro en mi respuesta, está en lo cierto. –

1

Agregaría índices a todo lo que esté unido, en la cláusula where o en la cláusula order by.

En este caso añadir índices de los siguientes (suponiendo campos de ID son claves primarias y ya han sido indexados):

  1. A.event
  2. B.event
  3. B.state
  4. B. Hur
  5. B.event, B.timestamp (índice combinado de ambos campos)

El quinto, al ser una combinación de índice, debe acelerar el orden por.

Debe atenuar el número de índices, frente a cualquier caída de rendimiento que tenga al insertar registros en la tabla (cuantos más índices agregue a la tabla, más lentos serán y serán actualizaciones, ya que los índices deben actualizarse) .

2

Es importante tener en cuenta que el orden de los campos en el índice es importante.

Un índice es, en cierto sentido, un árbol de búsqueda. Si indexa (B.event, B.state), el árbol agrupará todos los registros con el campo "evento" guardado, luego los ordenará por el campo "estado".

Si fuera a consultar ese índice para "b.state = x", el índice sería de poca utilidad; El índice es ordenado por el "evento" primero.


En su ejemplo:
- Un filtro por ella es "evento" campo
- A.event unirse a B.event
- B.state unirse a C.id
- Join B.hur = D.id
- Ordenar por B.event, B.timestamp

es importante tener en cuenta que el Optimize mirar las estadísticas de las tablas, los índices y, a continuación, puede volver a organizar el orden de las uniones. El resultado será el mismo, pero el orden puede ofrecer un rendimiento diferente, y el trabajo de los optimizadores es intentar encontrar el mejor rendimiento.

En su caso, esperaría que el pedido de B.event fuera extremadamente importante. Simplemente porque ese es el orden del resultado resultante, Y es el campo por el que filtra.

Luego se une a B.state to C.id. Entonces, tener e indexar en C.id es bueno, hace que la unión sea más rápida. Pero igualmente, tener los datos de la tabla B en un buen orden también puede hacer que la unión sea más rápida.

Pero, tener un índice en B.event y un índice separado en B.state puede rendir poco. El índice B.state se vuelve inútil porque estamos usando el índice B.event. Si combina los dos en un índice (b.event luego b.state), el plan de ejecución puede encontrar una forma de utilizar la parte b.state del índice.

Finalmente, si coloca todos los campos en el índice, el índice se hace más grande, pero es posible que la consulta nunca tenga que mirar la tabla. La información está en el índice. El tiempo necesario para pasar de un índice a la tabla para encontrar los campos "faltantes" es similar al de una combinación. Por lo tanto, para el rendimiento de lectura, agregar campos adicionales al índice puede ser muy útil.

estoy WITTERING en este momento, pero el resumen es el siguiente:
- Por lo general, índice separado en campos separados no se acostumbra juntos
- Para los índices compuestos, el orden que especifique los campos hace la diferencia
- Agregar campos 'adicionales' al índice lo hace más grande, pero también puede hacer consultas más rápido
- El orden del plan de ejecución es más importante que el orden de su consulta
- Pero los índices que tiene pueden determinar el orden de el plan de ejecución

Este tipo de trabajo tiene sin respuestas categóricas Depende tanto de tus datos que está más cerca de un arte.

Una opción es sobrecargar las tablas con índices, ver el plan de ejecución resultante y eliminar los índices que no son necesarios.

Pero incluso allí se aplica una advertencia. Debido a que el plan de ejecución depende de los datos (y de las estadísticas de la tabla), es muy importante tener datos del mundo real en las tablas. Si bien las tablas tienen 10 'o 100 s de filas, un plan de ejecución puede ser el más rápido. Pero cuando obtiene millones de filas, el plan de ejecución puede cambiar, y así beneficiarse de diferentes índices.

2

Ejecute explicar analizar la consulta, y léala - si no sirve de ayuda - ponga la salida de análisis de explicación en explain.depesz.com y compruebe lo que "dice".

Cuestiones relacionadas