GiST steht für „Generalized Search Tree" — ein flexibler Index-Framework für Datentypen, die nicht in B-tree's lineare Ordnung passen: Range-Typen mit Overlap-Logik, Geometrien, Volltext mit Updates, Nearest-Neighbor-Suche. Hier die wichtigsten Use-Cases.

Range-Overlap

SQL
CREATE TABLE bookings (
    id     bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    during tstzrange NOT NULL
);

CREATE INDEX bookings_during_idx ON bookings USING gist (during);

-- nutzt den GiST
SELECT * FROM bookings
WHERE during && '[2026-05-07 10:00, 2026-05-07 12:00)'::tstzrange;

&& ist Range-Overlap — finde alle Buchungen, die sich mit dem gegebenen Zeitfenster überschneiden. B-tree kann das nicht, GiST schon.

Operatoren auf Range-Typen mit GiST:

OperatorBedeutung
&&Überschneidet sich
@>Enthält
<@Ist enthalten in
-|-Ist benachbart
<<, >>Komplett vor / nach

Exclusion Constraints

GiST ist die Basis für Exclusion Constraints (siehe Artikel Exclusion Constraints):

SQL
CREATE EXTENSION IF NOT EXISTS btree_gist;

CREATE TABLE room_bookings (
    id      bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    room_id bigint NOT NULL,
    during  tstzrange NOT NULL,
    EXCLUDE USING gist (room_id WITH =, during WITH &&)
);

Postgres legt automatisch einen GiST-Index an, der den Exclusion Constraint absichert.

Geometrien (PostGIS)

Mit PostGIS-Extension wird GiST richtig spannend:

SQL
CREATE EXTENSION postgis;

CREATE TABLE locations (
    id   bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name text NOT NULL,
    geom geometry(Point, 4326) NOT NULL
);

CREATE INDEX locations_geom_idx ON locations USING gist (geom);

-- Nearest-Neighbor: 5 nächste Punkte zu einem gegebenen Standort
SELECT name
FROM locations
ORDER BY geom <-> ST_MakePoint(13.405, 52.52)::geography
LIMIT 5;

<-> ist der Distanz-Operator — und mit GiST-Index extrem schnell. Klassischer „5 Restaurants in der Nähe"-Use-Case.

Nearest-Neighbor — auch ohne PostGIS

Der <->-Operator funktioniert auch ohne PostGIS auf Standard-Typen:

SQL
CREATE TABLE points (
    id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    p  point NOT NULL
);

CREATE INDEX points_p_idx ON points USING gist (p);

SELECT * FROM points
ORDER BY p <-> point '(0,0)'
LIMIT 10;

Postgres' eingebauter point-Typ + GiST = simple K-Nearest-Neighbor-Suche ohne extra Extensions.

GiST vs. GIN für Volltext

Beide unterstützen tsvector:

GINGiST
LesenSchnellerLangsamer
SchreibenLangsamerSchneller
GrößeKleinerGrößer
Use-CaseSearch-heavyUpdates-heavy

In 95 % der Fälle: GIN nehmen. GiST nur, wenn Volltext-Daten häufig geupdated werden.

btree_gist für Mixed-Constraints

GiST kennt nativ keine Operatoren für einfache Typen wie bigint. Die Extension btree_gist schließt die Lücke:

SQL
CREATE EXTENSION btree_gist;

-- jetzt erlaubt:
EXCLUDE USING gist (room_id WITH =, during WITH &&)
--                  ^^^^^^^ bigint mit = via btree_gist

Ohne diese Extension müsste man ohne room_id-Spalte auskommen oder einen separaten Constraint pro Raum bauen — beides unhandlich.

Besonderheiten

GiST ist der Default für Range-Typen.

Ein B-tree auf einer tstzrange-Spalte indiziert die Ranges nur für =/</> (auf Range-Boundaries). Für && (Overlap) ist GiST zwingend. Wer mit Ranges arbeitet, sollte fast immer GiST nehmen.

<-> mit GiST = Nearest-Neighbor in O(log n).

Der Distanz-Operator nutzt den GiST-Index direkt — kein Vollscan. Bei einer Tabelle mit Millionen Punkten findet Postgres die K nächsten in Bruchteilen einer Sekunde. Funktioniert mit point, box, PostGIS-Geometrien und mehr.

GiST ist langsamer als B-tree für reine Equality.

Für WHERE id = 42 ist B-tree immer besser. GiST nur für die spezifischen Use-Cases (Range, Geometrie, Nearest-Neighbor). Wer Equality auf einer GiST-indizierten Spalte macht: B-tree zusätzlich anlegen.

GiST kann UNIQUE nicht — nur Exclusion.

Eindeutigkeit ist B-tree-Domäne. Aber mit EXCLUDE USING gist (col WITH =) kann man eindeutigkeits-äquivalente Logik mit Range-Constraints kombinieren.

SP-GiST für nicht-überlappende Hierarchien.

Variante: SP-GiST (Space-Partitioned GiST) ist optimiert für Daten ohne Überlappung — z. B. IP-Bereiche, Phone-Number-Präfixe. Anwendung selten, aber bei den richtigen Daten messbar schneller. USING spgist statt USING gist.

Plan-Optimizer wählt GiST oft konservativ.

Bei kleinen Tabellen oder wenig Selektivität greift Postgres oft zum Sequential Scan, auch wenn GiST verfügbar ist. Mit EXPLAIN ANALYZE prüfen, dann ggf. Statistiken refreshen oder Index-Setup überdenken.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Indexes

Zur Übersicht