Eu uso o PostgreSQL 9.1 no Ubuntu 12.04.
Preciso selecionar registros dentro de um intervalo de tempo: minha tabela time_limits
tem dois timestamp
campos e uma integer
propriedade. Existem colunas adicionais na minha tabela real que não estão envolvidas com 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 tabela contém aproximadamente 2 milhões de registros.
Consultas como as seguintes levavam muito tempo:
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';
Então tentei adicionar outro índice - o inverso do PK:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Fiquei com a impressão de que o desempenho melhorou: O tempo de acesso aos registros no meio da tabela parece ser mais razoável: algo entre 40 e 90 segundos.
Mas ainda são várias dezenas de segundos para valores no meio do intervalo de tempo. E mais duas vezes ao mirar no final da mesa (cronologicamente falando).
Tentei explain analyze
pela primeira vez obter este plano 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
Veja os resultados em depesz.com.
O que eu poderia fazer para otimizar a pesquisa? Você pode ver todo o tempo gasto verificando as duas colunas de carimbos de data/hora uma vez id_phi
definido como 0
. E não entendo a grande varredura (60 mil linhas!) nos carimbos de data e hora. Eles não são indexados pela chave primária e idx_inversed
eu adicionei?
Devo mudar de tipos de carimbo de data/hora para outra coisa?
Li um pouco sobre os índices GIST e GIN. Eu entendo que eles podem ser mais eficientes em certas condições para tipos personalizados. É uma opção viável para o meu caso de uso?