2009-05-19 10 views
16

Hier ist die Abfrage (die größte Tabelle hat etwa 40.000 Zeilen)langsame Abfrage bei der Verwendung von ORDER BY ist

SELECT 
    Course.CourseID, 
    Course.Description, 
    UserCourse.UserID, 
    UserCourse.TimeAllowed, 
    UserCourse.CreatedOn, 
    UserCourse.PassedOn, 
    UserCourse.IssuedOn, 
    C.LessonCnt 
FROM 
    UserCourse 
INNER JOIN 
    Course 
USING(CourseID) 
INNER JOIN 
(
    SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID 
) C 
USING(CourseID) 
WHERE 
    UserCourse.UserID = 8810 

Wenn ich dies ausführen, führt es sehr schnell (etwa 0,05 Sekunden). Es gibt 13 Zeilen zurück.

Wenn ich eine ORDER BY-Klausel am Ende der Abfrage (Reihenfolge von einer beliebigen Spalte) hinzufügen, dauert die Abfrage etwa 10 Sekunden.

Ich benutze diese Datenbank jetzt in der Produktion, und alles funktioniert gut. Alle meine anderen Fragen sind schnell.

Irgendwelche Ideen, was es sein könnte? Ich führte die Abfrage in MySQL Query Browser und von der Befehlszeile aus. Beide Orte waren mit der ORDER BY tot langsam.

EDIT: Tolgahan ALBAYRAK Lösung funktioniert, aber kann jemand erklären, warum es funktioniert?

+0

Warum funktioniert es? Eine Unterabfrage nimmt das Ergebnis in eine Ergebnismenge auf, und das Sortieren einer Ergebnismenge ist viel schneller, als wenn die Standardabfrageausführung auf dem Weg zählen würde. –

Antwort

15

vielleicht hilft:

SELECT * FROM ( 
    SELECT 
     Course.CourseID, 
     Course.Description, 
     UserCourse.UserID, 
     UserCourse.TimeAllowed, 
     UserCourse.CreatedOn, 
     UserCourse.PassedOn, 
     UserCourse.IssuedOn, 
     C.LessonCnt 
    FROM 
     UserCourse 
    INNER JOIN 
     Course 
    USING(CourseID) 
    INNER JOIN 
    (
     SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID 
    ) C 
    USING(CourseID) 
    WHERE 
     UserCourse.UserID = 8810 
) ORDER BY CourseID 
+0

Huh, das funktioniert (macht es schnell ausführen). Weißt du warum, obwohl? Das habe ich vorher noch nie gemacht. –

+0

40k ist nicht so viele Datensätze; In der Regel müssen sie sich mit Millionen befassen, da diese Unterschiede variieren können, aber dies kann dazu beitragen, die Leistung weiter zu verbessern, da die Joins auf einem reduzierten Datensatz durchgeführt werden. ... FROM (Select * from UserCourse Wo UserID = 8810 ) UserCourse – u07ch

+0

@Dude - die Verlangsamung kommt, weil es wahrscheinlich ist die Wahl der Bestellung zu tun, bevor die Verbindung zu tun. Wenn Sie die Reihenfolge in einer äußeren Abfrage festlegen, wird nur die ausgewählten Elemente sortiert. – tvanfosson

6

Ist die Spalte, die Sie bestellen, indexiert?

Indexierung beschleunigt die Bestellung und Filterung drastisch.

+0

Das angegebene op, das irgendeine Spalte in der Reihenfolge benutzt, verringert Leistung – northpole

+1

Jede Spalte, einschließlich die indizierten Spalten, lassen es langsam laufen. –

0

Sie die Statistiken auf Ihrer Datenbank aktualisiert? Ich stieß auf etwas ähnliches auf meiner, wo ich 2 identische Fragen hatte, wo der einzige Unterschied ein Großbuchstabe war und einer in 1/2 eine Sekunde zurückkam und der andere dauerte fast 5 Minuten. Die Aktualisierung der Statistik löste die Ausgabe

0

Eine ähnliche Frage vor here.

gefragt wurde, Es könnte Ihnen auch helfen. Im Grunde beschreibt es die Verwendung von zusammengesetzten Indizes und wie Reihenfolge nach funktioniert.

0

Heute hatte ich ein ähnliches Problem. Sobald ich die Ergebnismenge nach einem Feld aus einer verknüpften Tabelle sortiert hatte, war die gesamte Abfrage schrecklich langsam und dauerte mehr als hundert Sekunden.

Auf dem Server lief MySQL 5.0.51a und zufällig stellte ich fest, dass die gleiche Abfrage so schnell ausgeführt wurde, wie sie es immer auf einem Server mit MySQL 5.1 getan haben sollte. Beim Vergleich der Erklärungen für diese Abfrage habe ich gesehen, dass sich die Verwendung und Handhabung von Indizes offensichtlich sehr verändert hat (mindestens von 5.0 -> 5.1).

Also, wenn Sie ein solches Problem auftritt, vielleicht ist Ihre Auflösung einfach aktualisieren Sie Ihren MySQL

1

Antwort Verwirklichen zu spät ist, jedoch habe ich hatte gerade ein ähnliches Problem, durch erhöhte die Abfragezeit von Sekunden hinzugefügt, um 5 Minuten und die meisten anderen Vorschläge für die Beschleunigung versucht, bemerkt, dass die/tmp-Dateien, wo 12G für diese Abfrage zu bekommen. Die Abfrage wurde so geändert, dass ein zurückgegebenes varchar (20000) Feld "trim (" ed "und die Performance dramatisch verbessert wurde (zurück zu Sekunden). Ich denke also, es lohnt sich zu prüfen, ob Sie große Varchare als Teil Ihrer Anfrage zurückgeben. verarbeite sie (vielleicht substring (x, 1, length (x)) ?? wenn du sie nicht trimmen willst. Abfrage gab 500k Zeilen zurück und die Datei/tmp zeigte an, dass jede Zeile ungefähr 20k Daten verwendete.

1

Sie wählen aus "UserCourse" was ich nehme, ist eine Verbindungstabelle zwischen Kursen und Benutzern (Viele zu Viele). Sie sollten die Spalte, die Sie bestellen möchten, in der Tabelle "UserCourse" indizieren.

Angenommen, Sie „Auftrag von courseid“ wollen, dann müssen Sie indizieren es auf UserCourse Tisch.

Die Bestellung durch eine andere Spalte, die nicht in der Verbindungstabelle (d. H. UserCourse) vorhanden ist, erfordert möglicherweise eine weitere Denormalisierung und Indizierung auf der Verbindungstabelle, um für die Geschwindigkeit optimiert zu werden; Mit anderen Worten, Sie müssen eine Kopie dieser Spalte in der Verbindungstabelle haben und sie indizieren.

P.S. Die Antwort von Tolgahan Albayrak, obwohl für diese Frage korrekt, würde nicht das gewünschte Ergebnis in Fällen, in denen man eine "LIMIT x" Abfrage durchführen.

Verwandte Themen