Hallo Raketenwilli,
naja, ich hab gestern die freie PLZ/Ort/Koordinaten-Tabelle von Launix gefunden und die schreiben als Tipp, dass man einen Breitengrad mit 111,3km ansetzen kann und einen Längengrad mit 111,3km mal cos(breite). Das entspricht im Wesentlichen dem Erdumfang am Äquator entsprechend der aktuellen Referenzellipsoide (mit r=6378km). Nimmt man den Polradius von 6356km, kommt man auf 110,95km, d.h. der Längengradabstand 111,3km ist hierzulande um ein wenige hundert Meter zu groß. Angesichts der gegebenen Daten ist das irrelevant. Jedenfalls ist diese Rechnung einfacher als ein Orthodrome oder Entfernungsberechnungen auf dem Referenzellipsoid - bei letzterem müsste ich erstmal recherchieren, wie das überhaupt geht.
Damit hab ich dann einen inneren Select gemacht, um den Breiten- und Längenabstand zu Erftstadt zu bestimmen:
SET @bmin = 50.7933968978061-25/111.3,
@bmax = 50.7933968978061+25/111.3;
SET @lmin = 6.76938350029545-25/111.3/COS(@bmax),
@lmax = 6.76938350029545+25/111.3/COS(@bmax);
SELECT (Breite - 50.7933968978061)*111.3 AS dy,
(Laenge - 6.76938350029545)*111.3*COS(50.7933968978061) AS dx,
Plz, Ort, Breite, Laenge
FROM koordinaten
WHERE @bmin <= Breite AND Breite <= @bmax
AND @lmin <= Laenge AND Laenge <= @lmax
Die Einschränkung über @bmin & Co liefert ein Hüllentrapez - kein Rechteck. Wegen der Einschränkung über Längengrade ist der Abstand am Südrand etwas größer. Aber das ist ok so.
Und mit diesem SELECT hab ich dann die Distanzabfrage gefüttert:
SELECT Plz, Ort
FROM (
SELECT (Breite - @breite)*@distbreite AS dy,
(Laenge - @laenge)*@distlaenge AS dx,
Plz, Ort, Breite, Laenge
FROM koordinaten
WHERE @bmin <= Breite AND Breite <= @bmax
AND @lmin <= Laenge AND Laenge <= @lmax
) k
WHERE dx*dx+dy*dy < 25*25;
Einen Index auf Breite, Länge hab ich auch noch gesetzt, damit er das Hüllentrapez per Index-Scan anwenden kann. Eine Approximation ist es immer noch, weil @distlaenge auf die Breite des Suchortes bezogen ist. Aber wenn der Abstand nicht zu groß wird, ist das tolerierbar, finde ich.
Ohne das Hüllentrapez lief die Query in drei Ticks, mit Rechteck in einem Tick. Ein Tick ist 1/60s - genauer zeigt mir HeidiSQL das nicht an. Der Index auf BREITE/LAENGE war aber durchaus wichtig, ohne den brachte das Hüllentrapez kaum eine merkliche Beschleunigung.
Achso - die Laufzeit war deshalb im Bereich 50ms, weil ich die PLZ-Tabelle achtmal importiert habe und damit 66000 statt 8200 Zeilen durchsuche. Andernfalls wären meine Laufzeiten zu klein gewesen, um sie zu messen 🤣
Rolf
sumpsi - posui - obstruxi