J'utilise PostgreSQL 9.1 sur Ubuntu 12.04.
Je dois sélectionner des enregistrements dans une plage de temps: ma table time_limits
a deux timestamp
champs et une integer
propriété. Il y a des colonnes supplémentaires dans ma table réelle qui ne sont pas impliquées dans cette requête.
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Cette table contient environ 2 millions d'enregistrements.
Les requêtes suivantes ont pris énormément de temps:
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';
J'ai donc essayé d'ajouter un autre index - l'inverse du PK:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
J'ai l'impression que les performances se sont améliorées: le temps d'accès aux enregistrements au milieu de la table semble être plus raisonnable: entre 40 et 90 secondes.
Mais il reste encore plusieurs dizaines de secondes pour les valeurs situées au milieu de la plage de temps. Et deux fois plus lorsque vous visez la fin de la table (chronologiquement parlant).
J'ai essayé explain analyze
pour la première fois d'obtenir ce plan de requête:
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
Voir les résultats sur depesz.com.
Que puis-je faire pour optimiser la recherche? Vous pouvez voir tout le temps est passé numérise une fois que les deux colonnes horodatages id_phi
est définie sur 0
. Et je ne comprends pas le gros balayage (60 000 lignes!) Sur les horodatages. Ne sont-ils pas indexés par la clé primaire et idx_inversed
j'ai ajouté?
Devrais-je changer de type d'horodatage à autre chose?
J'ai lu un peu sur les index GIST et GIN. Je suppose qu'ils peuvent être plus efficaces à certaines conditions pour les types personnalisés. Est-ce une option viable pour mon cas d'utilisation?
explain analyze
sortie est l'heure à laquelle la requête a été requise sur le serveur . Si votre requête prend 45 secondes, le temps supplémentaire est utilisé pour transférer les données de la base de données au programme qui exécute la requête. Après tout, c'est 62682 lignes et si chaque ligne est grande (par exemple, a long varchar
ou text
colonnes), cela peut avoir un impact sur le temps de transfert drastiquement.
rows=62682 rows
est l' estimation du planificateur . La requête renvoie 0 ligne. (actual time=44.446..44.446 rows=0 loops=1)