Comme décrit, la réponse est "ni", pour les raisons suivantes:
- Prenez une table spatiale en 4326. Construisez un index spatial dessus. L'index spatial est un index plan, constitué des limites 2D des entités, en 4326, triées en une structure arborescente.
- (a) exécuter une requête de filtre de distance à l'aide d'un cast, comme
ST_DWithin(geom::geography, %anothergeom, %radius)
. Parce que la géographie est impliquée, le système recherchera un index de géographie (qui est construit sur une sphère, pas sur un plan) et n'en trouvera aucun. Puisqu'il n'a pas d'index, il effectuera la jointure en utilisant des analyses complètes des tables. Ce sera lent.
- (b) exécuter une requête de filtre de distance en utilisant une transformation, comme
ST_DWithin(ST_Transform(geom, 2163), %anothergeom, %radius)
. Vos tests ne sont pas contre la colonne indexée (geom), mais contre une fonction appliquée à la colonne ( ST_Transform(geom,2163)
) et donc encore une fois, votre index spatial ne sera pas utilisé. Ce sera lent.
Vous avez besoin que votre requête et votre index s'harmonisent. Si vous ne souhaitez pas modifier la projection de vos données, vous devrez utiliser un index fonctionnel, par exemple, si vous créez un index géographique de fonction, vous pouvez utiliser une requête basée sur la géographie:
CREATE INDEX mytable_geog_x
ON mytable USING GIST (geography(geom));
SELECT *
FROM mytable
WHERE ST_DWithin(geography(geom), %anothergeography, %radius);
Ou, dans le cas de la transformation:
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);
La performance la plus rapide absolue sera si vous convertissez les données de votre table en projection planaire (comme EPSG: 2163 ), créez un index spatial, puis utilisez ST_DWithin()
le résultat.
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)