J'ai une table PostgreSQL 9.1 avec des centaines de milliers de POINTS PostGIS. Pour chacun d'eux, j'aimerais trouver le point le plus proche dans un autre tableau de POINTS. Les points du deuxième tableau représentent une grille sur le monde entier, donc je sais qu'il y aura toujours une correspondance à 1 degré près. C'est la requête que j'utilise jusqu'à présent, qui utilise des index GIST, donc c'est assez rapide (environ 30 secondes au total).
SELECT DISTINCT ON (p.id)
p.id, ST_AsText(p.pos)
, ST_AsText(first_value(g.location) OVER (PARTITION BY p.id ORDER BY ST_Distance(p.pos, g.location::geography)))
FROM point p
JOIN grid g ON ST_DWithin(p.pos::geometry, g.location, 1)
Le seul problème est la ligne de données. Les points de la grille n'ont qu'une latitude 180, pas -180. Lorsque vous utilisez la version géométrique de ST_Distance, cela ne renvoie pas de points de l'autre côté de la ligne de données. Par exemple. si p.pos est POINT(-179.88056 -16.68833)
le point de grille le plus proche POINT(180 -16.25)
, mais la requête ci-dessus ne le renvoie pas. Quelle est la meilleure façon de résoudre ce problème?
Je ne veux pas vraiment avoir deux coordonnées pour un seul point de grille (-180 et +180). J'ai essayé d'ajouter ma propre fonction qui vérifie ce cas spécifique, mais la requête ne revient pas dans 5 minutes, probablement parce qu'elle ne peut plus utiliser l'index. J'ai également essayé d'utiliser la version géographique de ST_DWithin et cette requête n'est pas revenue non plus après 5 minutes.
Réponses:
OK, j'ai enfin trouvé un moyen de le pirater qui fonctionne non seulement autour du problème de la ligne de données, mais est également plus rapide.
J'ai été très surpris de voir que cette fonction, qui est appelée pour chaque ligne, est plus rapide que la fonction de fenêtre d'origine, mais elle est - plus de 10 fois plus rapide. Les performances de PostgreSQL sont vraiment un art noir!
la source