tengo una mesa
foo(a1, a2, a3, a4, a5) a1 es la clave principal. hay un índice no agrupado en a5 .
Tengo una consulta sencilla:
SELECT * FROM foo WHERE a5/100 = 20;Esta consulta se ejecuta significativamente más lento. actualizar las estadísticas utilizadas en la planificación de consultas no ayudó mucho.
¿Por qué podría estar pasando esto? ¿Qué podría estar haciendo mal? Soy nuevo en la optimización de consultas.
Está utilizando una expresión en la columna en el predicado WHERE, por lo que no se puede sargable (no puede usar un índice).
Esto deja de lado el posible problema de la cardinalidad, es decir, las distribuciones de datos: si sus condiciones DONDE devuelven más del 40% de la fila, un índice se vuelve inútil.
EDITAR
En un índice, busca un valor, si ese valor es el resultado de una expresión, el índice no se puede usar. Además, los operadores como : NOT, NOT IN,<> tampoco son sargable porque para una búsqueda de índice necesita un valor claro (s) para que el optimizador pueda definir algún tipo de rango fijo. Con sus cálculos sobre la marcha, el valor cambia constantemente, por lo que necesita escanear toda la tabla.
Puede crear un índice en expresiones en lugar de los datos base. Si sabe que siempre dividirá a5 por 100, puede hacer un índice con:
CREATE INDEX ON foo ((a5/100));Los soportes adicionales son necesarios.
De esta forma, cualquier consulta que tenga WHERE a5/100 = <something> podrá aprovechar el índice.
Sin embargo, no ayudará para WHERE a5/99 = <something> , etc.
Documentos en https://www.postgresql.org/docs/current/static/indexes-expressional.html