Ich benutze PostgreSQL 9.1 unter Ubuntu 12.04.
Ich muss Datensätze innerhalb eines bestimmten Zeitraums auswählen: Meine Tabelle time_limits
enthält zwei timestamp
Felder und eine integer
Eigenschaft. In meiner aktuellen Tabelle befinden sich zusätzliche Spalten, die nicht mit dieser Abfrage verknüpft sind.
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Diese Tabelle enthält ungefähr 2 Millionen Datensätze.
Abfragen wie die folgenden haben enorm viel Zeit in Anspruch genommen:
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';
Also habe ich versucht, einen weiteren Index hinzuzufügen - die Umkehrung der PK:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Ich hatte den Eindruck, dass sich die Leistung verbessert hat: Die Zeit für den Zugriff auf Datensätze in der Mitte der Tabelle scheint angemessener zu sein: irgendwo zwischen 40 und 90 Sekunden.
Bei Werten in der Mitte des Zeitbereichs sind es jedoch noch einige zehn Sekunden. Und zweimal mehr, wenn Sie das Ende der Tabelle anvisieren (chronologisch gesehen).
Ich habe explain analyze
zum ersten Mal versucht , diesen Abfrageplan zu erhalten:
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
Siehe die Ergebnisse auf depesz.com.
Was kann ich tun, um die Suche zu optimieren? Sie können sehen, wie viel Zeit für das Durchsuchen der beiden Zeitstempelspalten aufgewendet wurde, wenn auf eingestellt id_phi
ist 0
. Und ich verstehe den großen Scan (60K Zeilen!) Auf den Zeitstempeln nicht. Werden sie nicht durch den Primärschlüssel indiziert und idx_inversed
ich fügte hinzu?
Sollte ich von Zeitstempeltypen zu etwas anderem wechseln?
Ich habe etwas über GIST- und GIN-Indizes gelesen. Ich gehe davon aus, dass sie unter bestimmten Bedingungen für benutzerdefinierte Typen effizienter sein können. Ist es eine praktikable Option für meinen Anwendungsfall?
explain analyze
Ausgabe angegebene Zeit ist die Zeit, die die Abfrage auf dem Server benötigt . Wenn Ihre Abfrage 45 Sekunden dauert, wird die zusätzliche Zeit für die Übertragung der Daten von der Datenbank an das Programm aufgewendet, in dem die Abfrage ausgeführt wird. Immerhin sind es 62682 Zeilen. Wenn jede Zeile groß ist (z. B. lang varchar
oder spaltenweise text
), kann dies die Übertragungszeit beeinträchtigen drastisch.
rows=62682 rows
ist die Schätzung des Planers . Die Abfrage gibt 0 Zeilen zurück. (actual time=44.446..44.446 rows=0 loops=1)