2010-07-28 10 views
8

Perdiendo algunos problemas de rendimiento de DB en una aplicación EclipseLink/JPA bastante típica.¿En qué condiciones SELECCIONAR con PRIMARY KEY ser lento?

Estoy viendo consultas frecuentes que están tomando 25-100ms. Estas son consultas simples, simplemente seleccionando todas las columnas de una tabla donde su clave principal es igual a un valor. No deberían ser lentos

Estoy mirando el tiempo de consulta en el registro de postgres, usando log_min_duration_statement, por lo que esto debería eliminar cualquier sobrecarga de red o aplicación.

Esta consulta no es lenta, pero se usa con mucha frecuencia.

¿Por qué seleccionar * por clave principal sería lento? ¿Esto es específico para postgres o es un problema DB genérico? ¿Cómo puedo acelerar esto? ¿En general? Para postgres?

Consulta de ejemplo del registro de PG:

2010-07-28 08:19:08 PDT - LOG: duration: 61.405 ms statement: EXECUTE <unnamed> [PREPARE: SELECT coded_ele 
ment_key, code_system, code_system_label, description, label, code, concept_key, alternate_code_key FROM coded 
_element WHERE (coded_element_key = $1)] 

tabla tiene alrededor de 3,5 millones de filas.

También he ejecutado EXPLAIN y EXPLAIN ANALYZE en esta consulta, solo está haciendo un escaneo de índice.

+0

¿Qué tan grande es el conjunto de datos? ¿Qué tan grande es cada fila? ¿Cómo se ve la consulta? –

+0

¿Ha agrupado su base de datos? ¿Hiciste un análisis completo de vacío antes de publicar? ¿Y qué versión Pg? – jmz

+0

Sin clustering, tampoco es realmente una opción. Todavía no hice un análisis completo de vacío (lo haré) y este es PG 8.1. – Freiheit

Respuesta

4

Seleccionar * hace que su base de datos trabaje más y, como regla general, es una mala práctica. Hay toneladas de preguntas/respuestas en stackoverflow hablando de eso.

¿Has intentado reemplazar * con los nombres de los campos?

+1

JPA genera consultas tal como se describe con los nombres de los campos. Lo describí como "Seleccionar *" para abreviar. – Freiheit

+0

Ah, eso no se lo merecía entonces :-) Hay un millón de otras cosas que pueden afectar la permrmance ... las tablas de compactación o la reconstrucción de índices pueden ayudar, al configurar el relleno de índice para que sea más favorable a la lectura que a la escritura, al particionamiento (¿ en un disco más lento), columnas calculadas, cambiando el orden de campo en el SELECCIONAR (¿por qué? Aún no lo sé), etc. – dave

+0

Aceptado principalmente para el comentario de seguimiento en lugar de la respuesta inicial. Me dio una lista de cosas para entender y examinar para acelerar la consulta. – Freiheit

2

¿Podría estar recibiendo algún tipo de contención de bloqueo? ¿Qué tipo de bloqueos está tomando al realizar estas consultas?

+0

No estoy seguro. ¿Hay alguna forma de obtener PG o JPA para decirme cuándo se emite un bloqueo? – Freiheit

2

Bueno, no sé mucho sobre postgres SQL, así que le daré un consejo para MS SQL Server que podría ser aplicable.

MS SQL Server tiene el concepto de "índice de clúster" que es el diseño físico de los datos en el disco. Es bueno usarlo en el campo donde buscará un rango entre valores (principalmente campos de fecha). No sirve de mucho si está buscando un valor exacto (como una búsqueda de clave principal). Sin embargo, a veces el índice de la clave principal se establece inadvertidamente como un índice agrupado. Esto hace una búsqueda de índice en una exploración de tabla.

+0

¿Cómo el uso de un índice agrupado para una clave principal convierte una búsqueda de índice en clave primaria en una exploración de tabla? –

+0

Porque la tabla es el índice. Por lo tanto, "Escaneo de índice" == "Escaneo de tabla" –

+0

Pero la búsqueda de índice no va a ser un escaneo de índice, a menos que mi terminología se estropee. –

1

select * es casi siempre una muy mala idea.

  1. Si el orden de los campos cambia, se romperá el código. Según los comentarios, esto no es realmente importante dada la biblioteca de abstracción que está utilizando.
  2. Probablemente regrese más datos de la tabla de los que realmente desea. Seleccionar para los campos específicos que desee puede ahorrar tiempo de transferencia.

25ms es el límite inferior que verá en casi cualquier tipo de consulta SQL, ¡eso es solo dos accesos al disco! Es posible que desee buscar maneras de reducir el número de veces que se ejecuta la consulta en lugar de tratar de optimizar la consulta.

+0

¡Realmente me gustaría que la gente arruine COMENTARIOS cuando votan! –

+1

@Billy, se equivoca en dos cuentas: 1. El orden de campo no cambia a menos que suelte la tabla. 25 ms para PK es un tiempo muy largo. Sin embargo, esa no fue la razón del voto a favor. No respondió la pregunta, que era cómo resolver el problema, no cuántos accesos al disco aleatorios obtiene en 25 ms. – jmz

+0

@jmz: ALTER también puede cambiar el orden de los campos. En cuanto a la pregunta, creo que fue '¿Por qué seleccionar * por clave principal sería lento?', Seguido por '¿Cómo puedo acelerar esto?', En cuyo caso no veo cómo esto no responde la pregunta. –

1

¿La fila es inusualmente grande o contiene BLOB y grandes campos binarios?

¿Esto se realiza directamente a través de la consola o se está ejecutando esta consulta a través de alguna API de acceso a datos como jdbc o ADO.NET? Usted menciona JPA que se parece a una API de acceso a datos. Para consultas breves, la API de acceso a datos se convierte en un porcentaje mayor del tiempo de ejecución, creando el comando, creando objetos para contener las filas y las celdas, etc.

+0

Estas velocidades de consulta se registran desde los registros de postgres, por lo que es el tiempo de consulta real y no el tiempo de la API de datos (JPA). – Freiheit

Cuestiones relacionadas