Domina la regla del prefijo más a la izquierda, los índices cubridores y las trampas que hacen que un índice sea invisible para el planificador.
Abrir esta lección en KodokonUn índice compuesto ordena las filas sobre varias columnas, en el orden declarado. La regla decisiva es el prefijo más a la izquierda: un índice sobre (a, b) puede servir a un filtro sobre a, o sobre a y b, pero nunca sobre b solo. El orden de las columnas es por tanto una decisión de diseño, no un detalle. Primero crea el conjunto de datos de abajo.
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
department_id INTEGER,
salary INTEGER NOT NULL
);
INSERT INTO employees
(id, name, department_id, salary)
VALUES
(1, 'Ada', 1, 65000),
(2, 'Grace', 1, 72000),
(3, 'Alan', 2, 58000),
(4, 'Edsger', 1, 90000);Creemos un índice sobre (department_id, salary). Un filtro que empieza por department_id provoca un SEARCH. Pero un filtro solo sobre salary rompe el prefijo más a la izquierda: el planificador no puede saltar directamente a las filas correctas y recae en un SCAN. Compara los dos planes.
CREATE INDEX idx_dept_salary
ON employees (department_id, salary);
-- Leftmost prefix present: index used
EXPLAIN QUERY PLAN
SELECT id FROM employees
WHERE department_id = 1
AND salary > 60000;
-- SEARCH ... USING INDEX idx_dept_salary
-- Leading column missing: index ignored
EXPLAIN QUERY PLAN
SELECT id FROM employees
WHERE salary > 60000;
-- SCAN employeesUn índice cubridor contiene todas las columnas que lee la consulta. El planificador responde entonces directamente desde el índice, sin abrir la tabla: ese es el significado de USING COVERING INDEX. Aquí, el índice (department_id, salary) cubre una consulta que lee solo esas dos columnas. Recuerda que el id (el rowid) está presente de forma implícita en todos los índices, así que también queda cubierto sin coste.
-- Every column read is in the index
EXPLAIN QUERY PLAN
SELECT department_id, salary
FROM employees
WHERE department_id = 1;
-- SEARCH employees USING COVERING INDEX
-- idx_dept_salary (department_id=?)(department_id, salary), ¿qué consulta NO puede usarlo?email?