Quiero entender lo siguiente.
Supongamos que tengo una consulta complicada con, digamos, una combinación de 5 tablas por grupo por suma y orden.
Dejando a un lado las optimizaciones de la consulta en sí misma, por ejemplo, índices, etc.
¿Existe algún beneficio de rendimiento significativo con el uso LIMIT
? Supongo que toda la consulta (y los resultados) deben procesarse antes de que se aplique el LÍMITE, por lo que usar un LÍMITE para recuperar un subconjunto de los resultados, ¿ofrece esto alguna mejora significativa / notable?
mysql
performance
join
Jim
fuente
fuente
LIMIT
mejoran la eficiencia: Optimización de consultas LIMITRespuestas:
Si desea aprovechar
LIMIT
para mejorar el rendimiento, necesitaLIMIT
antesJOIN
Estos principios pueden recorrer un largo camino si puede orquestarlos.
Aprendí estos conceptos al ver este video de YouTube (escuche atentamente el acento francés)
Utilicé esos conceptos para responder una pregunta muy difícil de StackOverflow sobre cómo obtener los 40 artículos principales de algunas tablas: 12 de mayo de 2011: Obtener una sola fila de la tabla de unión .
En mi respuesta a esa pregunta (16 de mayo de 2011) , escribí la siguiente consulta y la probé a fondo:
Tenga en cuenta la línea en la consulta con el
LIMIT
Esta subconsulta está enterrada a tres niveles de profundidad. Esto me permitió obtener los últimos 40 artículos usando
LIMIT
. Luego, realicé las UNIONES necesarias después.LECCIONES APRENDIDAS
LIMIT
subconsultas internas puede no ser siempre la respuesta debido a la cardinalidad de los índices, el contenido de los datos y el tamaño del conjunto de resultados deLIMIT
. Si tiene todos sus "patos en una fila" (tenga los cuatro principios en mente para su consulta), puede obtener resultados sorprendentemente buenos.LIMIT
reuniendo solo claves.fuente
(A [LEFT] JOIN B) LIMIT 100
es equivalente a(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Donde[LEFT] JOIN
significa unión externa o interna(A LIMIT 100) [LEFT] JOIN B
. La idea es usarLIMIT
para determinar el tamaño del conjunto de resultados lo antes posible. También uso enLEFT JOIN
lugar deINNER JOIN
porqueLEFT JOIN
preservará el orden de las teclas en el lado izquierdo.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
generalmente se pueden reescribir como(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(no hay INNER JOIN aquí, con uniones internas que no serían equivalentes). El ejemplo de Rolando es exactamente ese caso.Cuando se ejecuta una consulta, primero se traduce en un plan compuesto por varios operadores. Hay dos tipos básicos de operadores: Bloqueo y No bloqueo. Un operador sin bloqueo recupera una fila (o algunas filas) de su hijo o hijos para cada fila que se le solicite. Un operador de bloqueo, por otro lado, tiene que leer y procesar todo el conjunto de filas de todos sus elementos secundarios antes de que pueda producir cualquier salida.
Sort es un operador de bloqueo típico. Por lo tanto, una selección con orden por no se beneficia mucho de un límite. Sin embargo, hay RDBMS que pueden utilizar un algoritmo de clasificación que necesita menos memoria y es más rápido cuando se proporciona una cláusula límite. En este caso, es suficiente almacenar las primeras n filas actualmente y moverlas de la memoria a medida que aparecen las filas anteriores. Eso puede ser una ganancia de rendimiento significativa. Sin embargo, no estoy 100% seguro de que MySQL tenga esa capacidad.
De cualquier manera, incluso una ordenación por límite aún necesita procesar todo el conjunto de filas de entrada antes de que pueda producir la primera fila de salida. Si bien este algoritmo, si se implementa, puede acelerar la clasificación, si el resto de la consulta es la parte más costosa, el tiempo total de ejecución no mejorará significativamente debido a un límite proporcionado.
fuente
GROUP BY
podría conducir a un plan que no contenga operadores de bloqueo.En mi caso, puedo decir que sí , incluso si (todavía) no entiendo por qué.
Tenga en cuenta el tiempo: 18 segundos. Misma solicitud con un LÍMITE grande:
¡Más de diez veces más rápido!
EXPLIQUE dar el mismo resultado para ambas solicitudes.
LIMIT debe interferir solo para limitar el conjunto de resultados (es decir, si hago un LIMIT 4, solo obtengo las primeras 4 filas del conjunto de resultados anterior).
fuente
LIMIT
. Su primera consulta se ejecuta en 18 segundos dando un conjunto de resultados. Todos los datos en la segunda consulta ya están almacenados en caché en el grupo de búferes de InnoDB debido a la primera consulta, por lo tanto, la segunda consulta debe ser más rápida, incluso si reinicia mysql, ejecute la primera consulta, reinicie mysql y ejecute la segunda consulta, obtendrá el mismo resultado. . Tener un mejor resultadoLIMIT
solo puede venir de hacer: 1)LIMIT
antesJOIN
, 2) LIMIT en orden de clasificaciónASC
oDESC
.