Consulta de caso A :
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Índice:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
No hay problema allí, ¿verdad? Si se usa el índice (para que coincida parcialmente con la WHERE
condición), aún necesitamos una operación de clasificación para ordenar los resultados por some_column
(que no está en el índice). También necesitamos una verificación adicional (Uso de Where) para mantener solo las filas que coinciden con la segunda condición. OKAY.
Caso B (la pregunta)
Consulta:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Índice:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
Entonces, ¿por qué no necesita una especie aquí ? Porque el índice es suficiente para ordenar como la consulta lo desea. Por supuesto, existe el problema adicional de la condición adicional ( AND placeholder = FALSE
) que no está cubierta por el índice.
Está bien, pero realmente no necesitamos una especie aquí. El índice nos puede proporcionar resultados que coinciden con la primera condición ( WHERE thread_id = 12345
) y están en el orden deseado para la salida. El único control adicional que necesitamos, y lo que hace el plan, es obtener las filas de la tabla, en el orden proporcionado por el índice, y verificar esta segunda condición hasta obtener 20 coincidencias. Eso es lo que significa ** Usando "".
Podemos obtener las 20 coincidencias en las primeras 20 filas (muy buenas y rápidas) o en las primeras 100 (todavía lo suficientemente rápido) o en las primeras 1000000 (probablemente muy, muy lento) o podemos obtener solo 19 coincidencias de tabla incluso después de leer todas las filas coincidentes del índice (realmente muy lento en una tabla grande). Todo depende de la distribución de datos.
Caso C (plan aún mejor)
Consulta:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Índice:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Ahora nuestro índice coincide con ambas condiciones y el orden por. El plan es bastante simple: obtenga las primeras * 20 coincidencias del índice y lea las filas correspondientes de la tabla. No se necesita verificación adicional (No "Usar dónde") ni ordenar (no "Usar ordenar archivos").
primero *: los primeros 20 cuando se lee el índice hacia atrás desde el final (como lo hemos hecho ORDER BY .. DESC
) pero eso no es un problema. Los índices del árbol B se pueden leer hacia adelante y hacia atrás con un rendimiento casi igual.