Wie beschrieben lautet die Antwort aus folgenden Gründen "weder":
- Nehmen Sie eine räumliche Tabelle in 4326. Erstellen Sie einen räumlichen Index darauf. Der räumliche Index ist ein planarer Index, der aus den 2D-Grenzen der Merkmale in 4326 besteht und in eine Baumstruktur sortiert ist.
- (a) Führen Sie eine Abstandsfilterabfrage mit einem Cast aus, wie z
ST_DWithin(geom::geography, %anothergeom, %radius)
. Da es sich um eine Geografie handelt, sucht das System nach einem Geografieindex (der auf einer Kugel und nicht auf einer Ebene erstellt wird) und findet keinen. Da es keinen Index hat, führt es den Join mit vollständigen Scans der Tabelle (n) durch. Es wird langsam sein.
- (b) Ausführen einer Abstandsfilterabfrage unter Verwendung einer Transformation wie
ST_DWithin(ST_Transform(geom, 2163), %anothergeom, %radius)
. Ihre Tests richten sich nicht gegen die indizierte Spalte (geom), sondern gegen eine Funktion, die auf die Spalte ( ST_Transform(geom,2163)
) angewendet wird. Daher wird Ihr räumlicher Index nicht verwendet. Es wird langsam sein.
Sie müssen Ihre Abfrage und Ihren Index harmonisieren. Wenn Sie die Projektion Ihrer Daten nicht ändern möchten, müssen Sie einen Funktionsindex verwenden. Wenn Sie beispielsweise einen Funktionsgeografieindex erstellen, können Sie eine geografiebasierte Abfrage verwenden:
CREATE INDEX mytable_geog_x
ON mytable USING GIST (geography(geom));
SELECT *
FROM mytable
WHERE ST_DWithin(geography(geom), %anothergeography, %radius);
Oder im Transformationsfall:
CREATE INDEX mytable_geog_x
ON mytable USING GIST (ST_Transform(geom, 2163));
SELECT *
FROM mytable
WHERE ST_DWithin(ST_Transform(geom, 2163), %another2163geometry, %radius);
Die absolut schnellste Leistung wird erzielt, wenn Sie die Daten in Ihrer Tabelle in eine planare Projektion (wie EPSG: 2163 ) konvertieren , einen räumlichen Index erstellen und dann ST_DWithin()
für das Ergebnis verwenden.
ALTER TABLE mytable
ALTER COLUMN geom
TYPE Geometry(Point, 2163)
USING ST_Transform(geom, 2163);
CREATE INDEX mytable_geom_x ON mytable USING GIST (geom);
SELECT *
FROM mytable
WHERE ST_DWithin(geom, %some2163geom, %radius)