Geo-Suche (Entfernung)-Optimierung in PHP/MySQL
Bei der Durchführung entfernungsbasierter Abfragen für große Tabellen, die Breitengrad-Längengrad-Paare enthalten, Die Optimierung der Abfrageleistung wird entscheidend. Bedenken Sie die folgenden Herausforderungen, denen sich eine MySQL-Abfrage gegenübersieht:
Begrenzen Sie den Suchbereich
Eine effiziente Lösung besteht darin, einen Begrenzungsrahmen um den interessierenden Bereich zu definieren. Die Abfrage kann dann Zeilen innerhalb dieses begrenzten Bereichs auswählen, wodurch die Anzahl der Entfernungsberechnungen erheblich reduziert wird. Der Artikel „Movable Type“ bietet eine detaillierte Anleitung zum Erstellen von Begrenzungsrahmen und deren Verwendung in SQL-Abfragen.
Vincenty-Formel für genauere Ergebnisse
Wenn die Haversine-Formel nicht ausreicht Genauigkeit kann die Vincenty-Formel eingesetzt werden. Dieses JavaScript-Beispiel demonstriert seine Implementierung zur Berechnung von Großkreisabständen:
// Vincenty formula to calculate great circle distance between 2 locations expressed as Lat/Long in KM function VincentyDistance($lat1,$lat2,$lon1,$lon2){ $a = 6378137 - 21 * sin($lat1); $b = 6356752.3142; $f = 1/298.257223563; $p1_lat = $lat1/57.29577951; $p2_lat = $lat2/57.29577951; $p1_lon = $lon1/57.29577951; $p2_lon = $lon2/57.29577951; $L = $p2_lon - $p1_lon; $U1 = atan((1-$f) * tan($p1_lat)); $U2 = atan((1-$f) * tan($p2_lat)); $sinU1 = sin($U1); $cosU1 = cos($U1); $sinU2 = sin($U2); $cosU2 = cos($U2); $lambda = $L; $lambdaP = 2*M_PI; $iterLimit = 20; while(abs($lambda-$lambdaP) > 1e-12 && $iterLimit>0) { $sinLambda = sin($lambda); $cosLambda = cos($lambda); $sinSigma = sqrt(($cosU2*$sinLambda) * ($cosU2*$sinLambda) + ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda) * ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda)); //if ($sinSigma==0){return 0;} // co-incident points $cosSigma = $sinU1*$sinU2 + $cosU1*$cosU2*$cosLambda; $sigma = atan2($sinSigma, $cosSigma); $alpha = asin($cosU1 * $cosU2 * $sinLambda / $sinSigma); $cosSqAlpha = cos($alpha) * cos($alpha); $cos2SigmaM = $cosSigma - 2*$sinU1*$sinU2/$cosSqAlpha; $C = $f/16*$cosSqAlpha*(4+$f*(4-3*$cosSqAlpha)); $lambdaP = $lambda; $lambda = $L + (1-$C) * $f * sin($alpha) * ($sigma + $C*$sinSigma*($cos2SigmaM+$C*$cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM))); } $uSq = $cosSqAlpha*($a*$a-$b*$b)/($b*$b); $A = 1 + $uSq/16384*(4096+$uSq*(-768+$uSq*(320-175*$uSq))); $B = $uSq/1024 * (256+$uSq*(-128+$uSq*(74-47*$uSq))); $deltaSigma = $B*$sinSigma*($cos2SigmaM+$B/4*($cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM)- $B/6*$cos2SigmaM*(-3+4*$sinSigma*$sinSigma)*(-3+4*$cos2SigmaM*$cos2SigmaM))); $s = $b*$A*($sigma-$deltaSigma); return $s/1000; } echo VincentyDistance($lat1,$lat2,$lon1,$lon2);
Fazit
Durch die Nutzung von Begrenzungsrahmen und die Berücksichtigung alternativer Entfernungsberechnungsmethoden können Sie erhebliche Verbesserungen erzielen die Leistung Ihrer Geosuchabfragen auf MySQL. Ob es sich um eine umfangreiche Suche oder eine kritische Komponente Ihrer Webanwendung handelt, diese Optimierungen verbessern das Benutzererlebnis und sorgen für einen effizienten Datenbankbetrieb.
Das obige ist der detaillierte Inhalt vonWie kann ich Geosuchabfragen in PHP/MySQL für entfernungsbasierte Suchen in großen Datensätzen optimieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!