de Martin LE TARNEC.

Distinguir los predicados de acceso y de filtro


La base de datos PostgreSQL usa tres diferentes métodos para aplicar las cláusulas (predicados) where:

Predicado de acceso (“Index Cond”)

Los predicados de acceso reflejan las condiciones de inicio y de fin del recorrido del nodo hoja.

Predicado de filtro del índice (“Index Cond”)

Los predicados de filtro de índice se aplican solamente durante el recorrido del nodo hoja. No contribuye a las condiciones de inicio y de fin y no limita el rango escaneado.

Predicado de filtro a nivel de tabla (“Filter”)

Los predicados sobre columnas que no son parte del índice son evaluadas a nivel de tabla. Para que eso suceda, la base de datos carga el registro desde la primera tabla (heap).

Nota

Los predicados de filtro sobre índice dan una falsa sensación de seguridad; aunque se usa un índice, el rendimiento se degrada rápidamente cuando el volumen de datos o la carga del sistema crece.

Los planes de ejecución PostgreSQL no muestran el acceso al índice y ofrecen de forma separada los predicados de filtro; ambos aparecen como “Index Cond” (condiciones de índice). Eso significa que el plan de ejecución debe compararse con la definición del índice para diferenciar los predicados de acceso de los predicados de filtro sobre índice.

Nota

El plan de ejecución PostgreSQL no provee suficiente información como para encontrar los predicados de filtro sobre índice.

Los predicados mostrados como “Filtro” son siempre predicados de filtro a nivel de tabla; incluso cuando se muestra una operación Index Scan.

Considera el siguiente ejemplo, que aparece en el Capítulo “Rendimiento y escabilidad” (create & insert script):

CREATE TABLE scale_data (
   section NUMERIC NOT NULL,
   id1     NUMERIC NOT NULL,
   id2     NUMERIC NOT NULL
)
CREATE INDEX scale_data_key ON scale_data(section, id1)

Sobre la columna ID2, que no está incluida dentro del índice, aparecen filtros select:

PREPARE stmt(int) AS SELECT count(*) 
                       FROM scale_data
                      WHERE section = 1
                        AND id2 = $1
EXPLAIN EXECUTE stmt(1)

El predicado ID2 aparece como "Filter" abajo de la operación Index Scan. Eso es porque PostgreSQL realiza el acceso a la tabla como parte de la operación Index Scan. En otras palabras, la operación TABLE ACCESS BY INDEX ROWID de Oracle se oculta dentro de la operación Index Scan PostgreSQL. Por tal motivo, es posible que los filtros Index Scan sobre columnas no estén incluidos dentro del índice.

Importante

Los predicados Filter de PostgreSQL son predicados de filtro a nivel de tabla, incluso cuando se muestra Index Scan.

Cuando se agrega un índice como en el Capítulo “Rendimiento y escabilidad”, se puede ver aparecer todas las columnas como “Index Cond”, independientemente de si tienen predicados de acceso o de filtro.

DEALLOCATE stmt

El plan de ejecución con el nuevo índice no muestra ninguna condición de filtro:

                      QUERY PLAN
------------------------------------------------------
Aggregate  (cost=14215.98..14215.99 rows=1 width=0)
  Output: count(*)
  -> Index Scan using scale_slow on scale_data 
     (cost=0.00..14208.51 rows=2989 width=0)
     Index Cond: (section = 1::numeric AND id2 = ($1)::numeric)

Se puede observar que la condición sobre ID2 no puede limitar el recorrido del nodo hoja porque el índice tiene una columna ID1 antes de ID2. Eso significa que Index Scan escaneará el rango entero para la condición SECTION=1::numeric y aplicará el filtro ID2=($1)::numeric sobre cada fila que cumpla con la cláusula sobre SECTION.

Sugerencia

Acerca del autor

Foto de Markus Winand

Markus Winand enseña SQL eficiente, en casa y online. Mejora el tiempo de desarrollo utilizando SQL moderno y optimiza el tiempo de ejecución con indexación inteligente. Su libro Rendimiento SQL explicado se ha convertido en lectura obligada sobre el tema.

Adquiere tu libro en Amazon

Portada de “Rendimiento SQL explicado”: Ardilla corriendo en la hierba

La esencia del tuning de SQL en 200 páginas

Compra en Amazon
(solo en papel)

Libro y PDF también disponible en la tienda de Markus.

Contratar a Markus

La manera más rápida y fácil de beneficiarse de su extenso conocimiento y experiencia.
Aprende más »

“Use The Index, Luke” de Markus Winand se halla bajo licencia Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
Aspectos legales | Contacto | SIN GARANTÍA | Marcas | Privacy | CC-BY-NC-ND 3.0 licencia