Yo uso PostgreSQL 9.1 en Ubuntu 12.04.
Necesito seleccionar registros dentro de un rango de tiempo: mi tabla time_limitstiene dos timestampcampos y una integerpropiedad. Hay columnas adicionales en mi tabla real que no están involucradas con esta consulta.
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Esta tabla contiene aproximadamente 2 millones de registros.
Consultas como las siguientes tomaron enormes cantidades de tiempo:
select * from time_limits as t
where t.id_phi=0
and t.start_date_time <= timestamp'2010-08-08 00:00:00'
and t.end_date_time >= timestamp'2010-08-08 00:05:00';
Así que intenté agregar otro índice, el inverso de la PK:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Tengo la impresión de que el rendimiento mejoró: el tiempo para acceder a los registros en el medio de la tabla parece ser más razonable: entre 40 y 90 segundos.
Pero todavía son varias decenas de segundos para valores en el medio del rango de tiempo. Y dos veces más al apuntar al final de la tabla (cronológicamente hablando).
Intenté explain analyzepor primera vez obtener este plan de consulta:
Bitmap Heap Scan on time_limits (cost=4730.38..22465.32 rows=62682 width=36) (actual time=44.446..44.446 rows=0 loops=1)
Recheck Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
-> Bitmap Index Scan on idx_time_limits_phi_start_end (cost=0.00..4714.71 rows=62682 width=0) (actual time=44.437..44.437 rows=0 loops=1)
Index Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
Total runtime: 44.507 ms
Ver los resultados en depesz.com.
¿Qué puedo hacer para optimizar la búsqueda? Puede ver todo el tiempo dedicado a escanear las dos columnas de marcas de tiempo una vez que id_phise establece en 0. Y no entiendo el gran escaneo (¡60K filas!) En las marcas de tiempo. ¿No están indexados por la clave principal y idx_inversedagregué?
¿Debo cambiar de tipos de marca de tiempo a otra cosa?
He leído un poco sobre los índices GIST y GIN. Supongo que pueden ser más eficientes en ciertas condiciones para tipos personalizados. ¿Es una opción viable para mi caso de uso?
explain analyzesalida es el tiempo que la consulta necesitó en el servidor . Si su consulta tarda 45 segundos, el tiempo adicional se gasta transfiriendo los datos de la base de datos al programa que ejecuta la consulta Después de todo, son 62682 filas y si cada fila es grande (por ejemplo, larga varcharo textcolumnas), esto puede afectar el tiempo de transferencia drásticamente
rows=62682 rowses la estimación del planificador . La consulta devuelve 0 filas. (actual time=44.446..44.446 rows=0 loops=1)