Ich habe eine Tabelle , die Daten Reservierung unter Verwendung der Spalten speichert starts_at
& ends_at
Jedes Mal , wenn ich die Tabelle bin Abfrage überlappende Reservierungen zu finden, ich habe eine Möglichkeit , eine der folgenden Abfragen mit:
SELECT * FROM reservations
WHERE starts_at < '2014-01-03 00:00:00'
AND ends_at >='2014-01-01 00:00:00';
Oder
SELECT * FROM reservations
WHERE tsrange(starts_at, ends_at) && ('2014-01-01 00:00:00', '2014-01-03 00:00:00')
Ich habe reguläre B-Tree-Indizes für die Spalten starts_at
und ends_at
, daher werden sie bei der ersten Abfrage immer verwendet. Sofern ich keinen funktionalen GiST-Index für den tsrange definiere, führt die zweite Abfrage einen vollständigen Scan durch.
create index tsrange_idx on reservations using gist(tsrange(starts_at, ends_at));
Meine Frage ist, wenn die Tabelle wächst, welcher Index wird schneller sein? Wahrscheinlich ist die Antwort offensichtlich, wenn man sich den Ausführungsplan für Abfragen ansieht, aber ich bin mit dem Lesen von EXPLAIN ANALYZE
Ausgaben nicht vertraut .
quelle
Antworten:
Zeitstempel mit B-Tree-Index
Ich schlage eine dritte Option vor : Solange Ihre Tabelle zwei
timestamp
Spalten enthält (die scheinbar definiert sindNOT NULL
), würde ich einen einzelnen mehrspaltigen Index mit entgegengesetzter Sortierreihenfolge verwenden (sofern keine anderen Überlegungen zutreffen):Mehr in dieser verwandten Antwort:
Schauen Sie sich für die Abfrage den SQL-Standardoperator an
OVERLAPS
:Mehr in dieser verwandten Frage zu SO:
Sollte schneller als zwei B-Tree-Indizes sein. Weniger Speicherplatz und billiger zu warten. Die Belastung für Schreibvorgänge ist gering
Bereichstyp mit GiST-Index
Bei großen Tabellen ist ein GiST-Index für einen Bereichstyp höchstwahrscheinlich schneller, da er besser skaliert. Der Speicher auf der Festplatte ist erheblich größer und die Indexwartung etwas teurer.
Wenn Sie diesen Weg gehen, ist es effizienter, Ihren Zeitstempel zunächst als Bereich (
tsrange
odertstzrange
) zu speichern . Ein einfacher GiST-Index ohne funktionalen Aspekt ist etwas schneller.Mit dem
&&
Operator "Überlappung" haben Sie bereits in der Frage angezeigt:Möglicherweise sind Sie auch an einer Ausschlussbeschränkung interessiert , um Überschneidungen durch das Design auszuschließen, die einen GiST-Index wie den oben genannten automatisch implementiert. Das Handbuch enthält ein Codebeispiel . Diese verwandte Antwort auf SO enthält weitere Details:
quelle