ORDER BY, GROUP BY y DISTINCT necesitan poner los valores en orden. Crea un índice sobre la columna objetivo y el paso de ordenación temporal desaparece del plan.
Cuando ordenas con ORDER BY y la columna objetivo no tiene índice, la base de datos tiene que sacar cada fila y luego ordenarlas.
El plan muestra esta ordenación temporal como USE TEMP B-TREE FOR ORDER BY (construye una estructura de trabajo temporal solo para hacer la reordenación).
Las cosas cambian en cuanto creas un índice sobre la columna por la que estás ordenando.
Un índice ya está en el orden de esa columna desde el momento en que se construye.
Recorre el orden del índice y el resultado sale de inmediato.
La ordenación temporal ya no es necesaria, y USE TEMP B-TREE desaparece del plan.
Una ordenación temporal reorganiza las 50 000 filas en una estructura de trabajo, así que el coste crece con el número de filas.
Incluso si LIMIT 10 devuelve solo las 10 primeras filas, elegir esas 10 primeras sigue significando reordenar cada fila primero — la carga no se reduce.
En este artículo probarás "eliminar la ordenación con un índice" en la práctica.
ORDER BY sin índice frente a con índiceSin un índice, ORDER BY saca cada fila y ejecuta una ordenación temporal (USE TEMP B-TREE). Añade un índice sobre la columna de ordenación y la base de datos simplemente recorre el orden del índice — no se necesita ordenación temporal.
-- Ejemplo: tomar las 10 primeras filas ordenadas por amount-- Con un índice, la base de datos solo recorre su ordenDROPINDEXIFEXISTS ix_demo;CREATEINDEXix_demoON perf_sales(amount);EXPLAIN QUERY PLANSELECT sale_id, amountFROM perf_salesORDER BY amountLIMIT10;
Imagina el requisito: "Queremos las ventas ordenadas por fecha para ver las primeras." Toma la consulta que ordena por sale_date y compara su plan con y sin índice, observando si aparece USE TEMP B-TREE FOR ORDER BY. Elimina y reconstruye el índice dentro de esta única ejecución de la consola para que el plan sea totalmente autocontenido. (Ejecútalo correctamente para revelar la explicación.)
① Primero, usa DROP INDEX IF EXISTS para eliminar el índice sobre sale_date, luego muestra EXPLAIN QUERY PLAN para las 10 primeras filas ordenadas por sale_date (el estado sin índice).
② Luego crea un índice de una sola columna sobre sale_date.
③ Muestra el plan para la misma consulta de ordenación de nuevo, y compáralo con ① para ver si la ordenación temporal desaparece.
Editor SQL
Ejecutar una consulta para ver el resultado
Esquema
Sin tablas
GROUP BY también puede apoyarse en el orden del índice
GROUP BY también necesita que las filas con el mismo valor se sitúen unas junto a otras para poder agruparlas.
Sin un índice, eso significa una ordenación temporal y USE TEMP B-TREE FOR GROUP BY en el plan.
Crea un índice sobre la columna de agrupación y las filas con el mismo valor ya son adyacentes en el orden del índice, así que la base de datos puede recortar los grupos solo recorriéndolo.
Por ejemplo, GROUP BY emp_id emparejado con un índice sobre emp_id significa que las filas de cada emp_id ya son consecutivas en el orden del índice, así que la agregación se ejecuta sin ordenación temporal.
Incluye también la columna agregada en el índice y evitarás además volver a la tabla base (el Index-Only Scan (índice cubriente) del artículo anterior).
GROUP BY se monta sobre el orden del índiceSin un índice, GROUP BY saca cada fila y las agrupa con una ordenación temporal (USE TEMP B-TREE). Añade un índice sobre la columna de agrupación y las filas con el mismo valor ya son consecutivas en el orden del índice — solo recórrelo para recortar los grupos.
-- Ejemplo: conteo por region-- Con un índice sobre region, GROUP BY no necesita ordenación temporalDROPINDEXIFEXISTS ix_demo;CREATEINDEXix_demoON perf_sales(region);EXPLAIN QUERY PLANSELECT region, COUNT(*)FROM perf_salesGROUP BY region;
Imagina el requisito: "Queremos el conteo de ventas por comercial." Toma la consulta que agrupa por emp_id y compara su plan con y sin índice, observando si aparece USE TEMP B-TREE FOR GROUP BY.
① Primero, usa DROP INDEX IF EXISTS para eliminar el índice, luego muestra EXPLAIN QUERY PLAN para la consulta que cuenta filas por emp_id (el estado sin índice).
② Luego crea un índice de una sola columna sobre emp_id.
③ Muestra el plan para la misma consulta agregada de nuevo, y compáralo con ① para ver si la ordenación temporal desaparece.
Editor SQL
Ejecutar una consulta para ver el resultado
Esquema
Sin tablas
DISTINCT elimina su ordenación temporal de la misma manera
DISTINCT (que descarta duplicados y devuelve solo valores únicos) también necesita los valores alineados para detectar los duplicados, así que sin un índice provoca una ordenación temporal con USE TEMP B-TREE FOR DISTINCT.
El mecanismo es el mismo que el de GROUP BY: con un índice sobre la columna objetivo, los valores idénticos ya son adyacentes en el orden, así que eliminar duplicados es solo cuestión de comparar cada vecino.
Para SELECT DISTINCT product FROM perf_sales, donde quieres los valores únicos de una sola columna, un índice sobre product elimina la necesidad de una ordenación temporal.
Ordenar, agrupar y deduplicar comparten todos la característica de ser "operaciones que necesitan valores alineados" — y un índice sobre la columna objetivo te permite esquivar la ordenación temporal en cualquiera de ellas.
ORDER BY / GROUP BY / DISTINCT — mismo mecanismo, mismo arregloOrdenar, agrupar y deduplicar necesitan valores alineados. Un índice sobre la columna objetivo te permite recorrer el orden directamente y saltarte USE TEMP B-TREE en las tres.
-- Ejemplo: obtener los valores únicos de region-- Un índice sobre region evita la ordenación temporal de DISTINCTDROPINDEXIFEXISTS ix_demo;CREATEINDEXix_demoON perf_sales(region);EXPLAIN QUERY PLANSELECT DISTINCT regionFROM perf_sales;
Imagina el requisito: "Queremos la lista de códigos de producto que hemos manejado, sin duplicados." Toma la consulta que devuelve los valores únicos de product y compara su plan con y sin índice, observando si aparece USE TEMP B-TREE FOR DISTINCT.
① Primero, usa DROP INDEX IF EXISTS para eliminar el índice, luego muestra EXPLAIN QUERY PLAN para la consulta que devuelve los valores únicos de product (el estado sin índice).
② Luego crea un índice de una sola columna sobre product.
③ Muestra el plan para la misma consulta de deduplicación de nuevo, y compáralo con ① para ver si la ordenación temporal desaparece.
Editor SQL
Ejecutar una consulta para ver el resultado
Esquema
Sin tablas
QUIZ
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 1Cuando ejecutas ORDER BY sobre una columna sin índice, ¿cuál aparece en el plan?
Pregunta 2¿Por qué un índice permite a GROUP BY emp_id saltarse la ordenación temporal?
Pregunta 3¿Cuál es la razón compartida por la que un índice puede saltarse la ordenación temporal en ORDER BY / GROUP BY / DISTINCT?