2016-08-31 2 views
0

Ich habe die folgende MySQL-Abfrage, die auf einer Tabelle mit etwa 50.000 Datensätze ausgeführt wird. Die Abfrage gibt Datensätze innerhalb eines 20-Meilen-Radius zurück und ich verwende ein Begrenzungsfeld in der WHERE-Klausel, um die Datensätze einzugrenzen. Die Abfrage ist nach Entfernung sortiert und auf 10 Datensätze beschränkt, da sie auf einer paginierten Seite verwendet wird.MYSQL Abfrage-Leistung - Suche nach Entfernung

Die Abfrage dauert derzeit im Durchschnitt 0,0210 Sekunden, aber weil die Website so beschäftigt ist, suche ich nach Möglichkeiten, dies zu verbessern.

Die Anzeigentabelle enthält etwa 20 Spalten und einen Index für die Spalten für die Länge und Breite.

Kann jemand trotzdem die Leistung dieser Abfrage verbessern? Ich habe darüber nachgedacht, eine separate Tabelle zu erstellen, die nur die Felder advert_id, longitude und latitude enthält. Aber ich habe mich gefragt, ob jemand andere Vorschläge oder Möglichkeiten zur Verbesserung der folgenden Abfrage hatte?

SELECT adverts.advert_id, 
     round(sqrt((((adverts.latitude - '52.536320') * 
      (adverts.latitude - '52.536320')) * 69.1 * 69.1) + 
      ((adverts.longitude - '-2.063380') * 
      (adverts. longitude - '-2.063380') * 53 * 53)), 
      1) as distance FROM adverts 
    WHERE (adverts.latitude BETWEEN 52.2471737281 AND 52.8254662719) 
     AND (adverts.longitude BETWEEN -2.53875093307 AND -1.58800906693) 
    having (distance <= 20) 
    ORDER BY distance ASC 
    LIMIT 10 

Antwort

0

Sie müssen räumliche Datenformate und räumliche Indizes verwenden: how to use them.

Insbesondere müssen Sie das POINT-Datenformat verwenden, um sowohl den Breiten- als auch den Längengrad in einer einzelnen Spalte zu speichern. Anschließend fügen Sie dieser Spalte einen räumlichen Index hinzu.

Der räumliche Index wird normalerweise als R-Baum (oder Ableitungen) implementiert, so dass die Kosten für die Suche nach allen Punkten in einem bestimmten Bereich logarithmisch sind.

+0

Lassen Sie uns sehen SHOW CREATE TABLE. Welche Version von MySQL? –

+0

@RickJames Die obige Dokumentation bezieht sich auf mysql 5.7, also funktioniert es zumindest für alle Versionen von dieser Version (aber ich erinnere mich, dass ich die meisten Features auch in älteren Versionen gesehen habe). [there] (https://dev.mysql.com/doc/refman/5.7/de/creating-spatial-indexes.html) gibt es ein gutes Beispiel für create table, wo Sie auch einen räumlichen Index hinzufügen. Ersetzen Sie einfach GEOMETRIE durch POINT. In diesem Fall ist die einzige angelegte Spalte auch der Primärschlüssel; Wenn Sie doppelte Punkte speichern möchten, müssen Sie natürlich eine weitere Spalte hinzufügen, um sie als Primärschlüssel zu verwenden. –

+0

Hoppla, wahrscheinlich meine Frage für @Mark. –