2015-04-20 12 views
13

Ich bin neu in MySQL haben, aber die folgende Abfrage erstellt, dieoptimieren Zunder Typ mysql query

  1. in der Nähe Benutzer findet eine Tabelle von latlong POINTs (Tabelle pos) verwenden.
  2. Entfernt Benutzer, die bereits bewertet wurden (Table Swipes).
  3. Verbindet die Ergebnisse mit der Benutzertabelle.

Z.B. Leute finden, in der Nähe von POINT (95,95) für Benutzer mit id = 1 (latlong Werte vereinfacht)

SELECT users.id, name, email, gender, birthyear, latlong FROM (
SELECT * FROM (
    # Find nearby users. 
    SELECT * FROM pos 
     WHERE X(latlong) BETWEEN 90.0 AND 100.0 
     AND Y(latlong) BETWEEN 90.0 AND 100.0 
) AS nearby WHERE owner NOT IN (
    # Find users already rated. 
    SELECT target FROM swipes WHERE owner = 1 
) AND id != 1 
) AS unratedNearby JOIN users ON unratedNearby.owner = users.id; 

alles perfekt, aber ich bin besorgt über die Komplexität dieser Abfrage und wie das funktioniert, wird es skaliert werden. Ich habe eine SPATIAL KEY 'latlong' ('latlong') auf Tisch pos (ich weiß, dies ist eine suboptimale Möglichkeit, in der Nähe von Benutzern zu finden, aber Genauigkeit ist nicht so wichtig hier). Jeder Benutzer kann unendlich viele Wischbewegungen ausführen.

Wird diese Abfrage abbrechen, wenn die Tabellen "users" und "swipes" sehr groß werden? Gibt es irgendwelche Indizes, die ich neben dem räumlichen Schlüssel verwenden sollte?

+0

Sie sollten mehr Informationen über Ihre Tabellen Struktur und mindestens erklären, warum Antworten unten nicht qualifizieren – RuslanN

Antwort

3

Ihre Abfrage scheint für diese einfache Aufgabe zu kompliziert. Ihre Methode in der Nähe Nutzer finden, scheint wirklich ungenau für Menschen task.Consider diese Abfrage mit haversine formula als Abstandsfunktionen zu finden (Beispiele dieser Funktionen können einfach online gefunden werden)

SELECT user_id,name,email,gender,birthyear,latlong,distance(latlong) as  
distance 
FROM pos p left join swipes s on p.user_id = s.owner 
WHERE target_id is NULL 
ORDER by distance asc 

Diese Abfrage kann falsch sein, weil Sie haven‘ t hat Ihre create table-Anweisungen bereitgestellt. Aber Logik ist richtig. Sie schließen sich der Tabelle der Position der Benutzer auf der Tabelle der Wischen an und nehmen Sie die Reihen ohne Aufzeichnungen, als Sie Ihre Ergebnisse nach der Entfernung bestellen, um die nahen Menschen zu bekommen.

0

Skalierung ist ein Problem mit "finden in der Nähe". Naive Lösungen sind O (N * N); die meisten Lösungen sind O (N).

Here is a solution, aber es beinhaltet eine Umstrukturierung der Daten. Es ist O (1). Beispielcode befindet sich im Blog.

0

Haben Sie darüber nachgedacht, die GAE Search API zu verwenden, um die "nächstgelegenen" Benutzer abzurufen und anschließend nach Benutzern in dieser Liste nach gesperrten Benutzern zu suchen?

+0

Das sieht ideal aus, außer die Suche API hat keine Entsprechung einer Tabellenzusammenführung, wo ich Leute entfernen konnte, die der Benutzer bereits geklaut hat. –

+0

Leider glaube ich nicht, dass Sie in der Lage sein werden, eine Tabellenzusammenführung so zu machen, dass sie wirklich skaliert. Wahrscheinlich müssen Sie die Vorgänge aufteilen. – jirungaray