2009-05-19 25 views
16

Aquí está la consulta (la tabla más grande tiene alrededor de 40.000 filas)consulta lenta cuando se utiliza ORDER BY

SELECT 
    Course.CourseID, 
    Course.Description, 
    UserCourse.UserID, 
    UserCourse.TimeAllowed, 
    UserCourse.CreatedOn, 
    UserCourse.PassedOn, 
    UserCourse.IssuedOn, 
    C.LessonCnt 
FROM 
    UserCourse 
INNER JOIN 
    Course 
USING(CourseID) 
INNER JOIN 
(
    SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID 
) C 
USING(CourseID) 
WHERE 
    UserCourse.UserID = 8810 

Si funciono esto, se ejecuta muy rápidamente (.05 segundos aproximadamente). Devuelve 13 filas.

Cuando agrego una cláusula ORDER BY al final de la consulta (ordenando por cualquier columna) la consulta tarda unos 10 segundos.

Estoy usando esta base de datos en producción ahora, y todo está funcionando bien. Todas mis otras consultas son rápidas.

¿Alguna idea de lo que podría ser? Ejecuté la consulta en el buscador de consultas de MySQL y desde la línea de comandos. En ambos lugares estaba muerto lento con el ORDER BY.

EDIT: La solución Tolgahan ALBAYRAK funciona, pero ¿alguien puede explicar por qué funciona?

+0

¿Por qué funciona? una subconsulta toma el resultado en un conjunto de resultados, y ordenar un conjunto de resultados es mucho más rápido que contar con la ejecución de la consulta predeterminada para ordenar en el camino. –

Respuesta

15

tal vez esto ayuda:

SELECT * FROM ( 
    SELECT 
     Course.CourseID, 
     Course.Description, 
     UserCourse.UserID, 
     UserCourse.TimeAllowed, 
     UserCourse.CreatedOn, 
     UserCourse.PassedOn, 
     UserCourse.IssuedOn, 
     C.LessonCnt 
    FROM 
     UserCourse 
    INNER JOIN 
     Course 
    USING(CourseID) 
    INNER JOIN 
    (
     SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID 
    ) C 
    USING(CourseID) 
    WHERE 
     UserCourse.UserID = 8810 
) ORDER BY CourseID 
+0

Huh, eso funciona (lo hace ejecutar rápidamente). ¿Sabes por qué? Nunca tuve que hacer eso antes. –

+0

40k no es que muchos registros; Por lo general, tienen que lidiar con millones de millas de soya que pueden variar, pero esto puede ayudar a mejorar el rendimiento aún más, ya que las uniones se realizarán en un conjunto de datos reducido. ... DE (Select * from UserCourse Dónde UserID = 8810 ) UserCourse – u07ch

+0

@Dude - la desaceleración viene porque es probable que sea la elección de hacer el pedido antes de hacer la unión. Hacer el pedido en una consulta externa lo obliga a ordenar solo los elementos seleccionados. – tvanfosson

6

¿Está indexada la columna que está ordenando?

La indexación acelera drásticamente el orden y el filtrado.

+0

la operación mencionada utilizando cualquier columna en el orden por reduce el rendimiento – northpole

+1

Cualquier columna, incluidas las columnas indexadas, la hacen funcionar lenta. –

0

¿Ha actualizado las estadísticas de su base de datos? Me encontré con algo similar en el mío donde tuve 2 consultas idénticas donde la única diferencia era una letra mayúscula y una vuelta en 1/2 por segundo y la otra tardó casi 5 minutos. La actualización de las estadísticas resuelto el problema

0

Una pregunta similar se preguntó antes here.

Podría ayudar también. Básicamente, describe el uso de índices compuestos y la forma en que funciona.

0

Hoy me encontré con el mismo tipo de problema. Tan pronto como clasifiqué el conjunto de resultados por un campo de una tabla unida, toda la consulta fue terriblemente lenta y tardó más de cien segundos.

El servidor ejecutaba MySQL 5.0.51a y, por casualidad, noté que la misma consulta se ejecutaba tan rápido como debería haber hecho siempre en un servidor con MySQL 5.1. Al comparar las explicaciones de esa consulta, vi que obviamente el uso y manejo de los índices ha cambiado mucho (al menos desde 5.0 -> 5.1).

Así que si se encuentra con un problema, tal vez su resolución es simplemente actualizar su MySQL

1

Darse cuenta de respuesta es demasiado tarde, sin embargo yo sólo he tenido un problema similar, la adición de orden por el aumento del tiempo de consulta de segundos a 5 minutos y habiendo probado la mayoría de las otras sugerencias para acelerarlo, notó que los archivos/tmp eran 12G para esta consulta. Se modificó la consulta de modo que un campo varchar (20000) que se devolvió fue "trim (" ed) y el rendimiento mejoró dramáticamente (de regreso a segundos). Así que supongo que vale la pena verificar si está devolviendo varchar grandes como parte de su consulta y, si es así, procesarlos (tal vez subcadena (x, 1, longitud (x)) ?? si no desea recortarlos. La consulta devolvió 500k filas y el archivo/tmp indicó que cada fila estaba usando aproximadamente 20k de datos.

1

Usted está seleccionando de "UserCourse", que supongo que es una tabla de unión entre cursos y usuarios (Muchos a muchos). Debe indexar la columna que necesita para ordenar, en la tabla "UserCourse".

Suponga que quiere "ordenado por courseid", entonces usted necesita para indexarlo en UserCourse mesa.

Ordenar por cualquier otra columna que no está presente en la tabla de unión (es decir UserCourse) puede requerir más desnormalización y la indexación sobre la mesa de unirse que ser optimizado para la velocidad; En otras palabras, debe tener una copia de esa columna en la tabla de unión e indexarla.

P. S. La respuesta dada por Tolgahan Albayrak, aunque es correcta para esta pregunta, no produciría el resultado deseado, en los casos en que se está haciendo una consulta "LIMIT x".

Cuestiones relacionadas