2012-10-05 8 views
12

Im Anschluss an meiner vorherigen Frage zu diesem Thema Postgres combining multiple Indexes:Postgres GIST vs Btree Index

Ich habe die folgende Tabelle auf Postgres 9.2 (mit postgis):

CREATE TABLE updates (
    update_id character varying(50) NOT NULL, 
    coords geography(Point,4326) NOT NULL, 
    user_id character varying(50) NOT NULL, 
    created_at timestamp without time zone NOT NULL 
); 

Und ich bin mit Abfrage folgend auf dem Tisch:

select * 
from updates 
where ST_DWithin(coords, ST_MakePoint(-126.4, 45.32)::geography, 30000) 
and user_id='3212312' 
order by created_at desc 
limit 60 

Also da, was Index sollte ich für (coords + user_id), GIST oder BTree?

CREATE INDEX ix_coords_user_id ON updates USING GIST (coords, user_id); 

ODER

CREATE INDEX ix_coords_user_id ON updates (coords, user_id); 

Ich las, dass BTree als GIST besser abschneidet, aber bin ich GIST zu verwenden gezwungen, da ich postgis Geographie Feld bin mit ??

+0

Bitte zeigen Sie 'erklären analysieren' für beide; Fügen Sie die Pläne auf http://explain.depesz.com/ ein und verlinken Sie sie hier. –

Antwort

11

Sie müssen GiST verwenden, wenn Sie eine andere Indexmethode als die normalen b-tree-Indizes (oder Hash-Indizes, aber sie sollten nicht wirklich verwendet werden) verwenden möchten. PostGIS-Indizes erfordern GiST.

B-Tree-Indizes können nur für Grundoperationen verwendet werden, Gleichheit oder der Bestellung beteiligt, wie =, <, <=, >, >=, <>, BETWEEN und IN. Während Sie einen B-Tree-Index für ein Geometrieobjekt (Punkt, Region usw.) erstellen können, kann er nur tatsächlich für die Gleichheit verwendet werden, da Ordnungsvergleiche wie > für solche Objekte im Allgemeinen bedeutungslos sind. Ein GiST-Index wird benötigt, um komplexere und allgemeinere Vergleiche wie "enthält", "schneidet" usw. zu unterstützen.

Sie können btree_gist extension verwenden, um die B-Tree-Indizierung für GiST zu aktivieren. Es ist deutlich langsamer als normale B-Tree-Indizes, aber ermöglicht es Ihnen, einen mehrspaltigen Index zu erstellen, die sowohl Gist-nur-Typen und regelmäßige Typen wie text enthält, integer usw.


In diesen Situationen, die Sie wirklich brauchen zu verwenden explain analyze (explain.depesz.com ist nützlich für dieses) zu untersuchen, wie Pg verschiedene Indizes und Kombinationen von Indizes verwendet, die Sie erstellen. Probieren Sie verschiedene Spaltenreihenfolgen in mehrspaltigen Indizes aus und prüfen Sie, ob zwei oder mehr separate Indizes effektiver sind.

Ich vermute stark, dass Sie in diesem Fall die besten Ergebnisse mit dem mehrspaltigen GiST-Index erhalten, aber ich würde versuchen, mehrere verschiedene Kombinationen von Indizes und Indexspaltenordnungen zu sehen.

+0

Aber ich bin in der Lage, multi-column Index auf (coords, user_id) mit btree zu erstellen, also nicht sicher, welchen Vorteil gibt ein langsamer GIST-Index hier? – kapso

+2

@ user310525 Nur weil Sie den Index erstellen können, heißt das nicht, dass er etwas Nützliches für Sie tut. Untersuchen Sie 'explain analyze'-Ausgabe, um zu sehen, welche Indizes verwendet werden und wie. B-Tree-Indizes können nur für '=', '<', '<=', '>', '> =', '<>' und 'BETWEEN' verwendet werden - also ist es wahrscheinlich, dass es überhaupt nicht gut für den PostGIS-Teil Ihrer Anfrage ist Sie wären besser dran mit einem einzigen Spalten-B-Tree-Index für '(user_id)'. –

+0

@ user310525 'ST_DWithin' ist dokumentiert, um alle verfügbaren Geometrie-Indizes zu verwenden, daher sollte es vom GiST-Index profitieren, aber ich bezweifle, dass es einen b-tree-Index für den Geometrie-Typ verwenden kann, es sei denn, es kann einen Gleichheitsvergleich durchführen. –