Heim > Datenbank > MySQL-Tutorial > Hauptteil

Wie kann ich Geosuchabfragen in PHP/MySQL für entfernungsbasierte Suchen in großen Datensätzen optimieren?

DDD
Freigeben: 2024-11-13 09:42:02
Original
253 Leute haben es durchsucht

How can I optimize geo-search queries in PHP/MySQL for distance-based searches on large datasets?

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:

  • MySQL durchläuft alle Zeilen, was hohe Rechenkosten verursacht.
  • Geodatenerweiterungen wie R-Trees können komplex sein und mathematisches Fachwissen erfordern.

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);
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage