2011-03-05 12 views
90

Ejemplo muy simple - una tabla, un índice, una consulta:¿Por qué PostgreSQL realiza un escaneo secuencial en una columna indexada?

CREATE TABLE book 
(
    id bigserial NOT NULL, 
    "year" integer, 
    -- other columns... 
); 

CREATE INDEX book_year_idx ON book (year) 

EXPLAIN 
SELECT * 
    FROM book b 
    WHERE b.year > 2009 

me da:

Seq Scan on book b (cost=0.00..25663.80 rows=105425 width=622) 
    Filter: (year > 2009) 

Por qué no realiza exploración de índice en su lugar? ¿Qué me estoy perdiendo?

Respuesta

135

Si el SELECT devuelve más de aproximadamente el 5-10% de todas las filas en la tabla, un escaneo secuencial es mucho más rápido que un escaneo de índice.

Esto se debe a que un escaneo de índice requiere varias operaciones de IO para cada fila (busque la fila en el índice, luego recupere la fila del montón). Mientras que un escaneo secuencial solo requiere un IO individual para cada fila, o incluso menos porque un bloque (página) en el disco contiene más de una fila, por lo que se puede obtener más de una fila con una sola operación IO.

Por cierto: esto es cierto para otros DBMS también - algunas optimizaciones como "índice sólo se analizan los" llevado aparte (pero para un SELECT * es muy poco probable tal un DBMS iría para un "índice sólo escanear")

+6

El 5-10% depende de un par de ajustes de configuración y el almacenamiento de los datos también. No es un número difícil. –

+4

@Frank: es por eso que dije "aproximadamente" :) Pero gracias por señalarlo –

+0

Interesante, eso explica muchas cosas para mí :) De hecho, cuando selecciono por año> 2010 lo hace index scan. ¡Gracias! – wajda

8

¿Sabía que ANALYZE la tabla/base de datos? ¿Y el statistics? Cuando hay muchos registros en el año> 2009, un escaneo secuencial puede ser más rápido que un escaneo de índice.

Cuestiones relacionadas