Ich möchte folgendes verstehen.
Angenommen, ich habe eine komplizierte Abfrage mit einem Join von 5 Tabellen pro Gruppe nach Summierungen und Reihenfolge nach.
Abgesehen von Optimierungen an der Abfrage selbst, z. B. Indizes usw.
Gibt es einen signifikanten Leistungsvorteil bei der Verwendung LIMIT
? Ich gehe davon aus, dass alle Abfragen (und Ergebnisse) verarbeitet werden müssen, bevor LIMIT angewendet wird. Wenn Sie also ein LIMIT verwenden, um eine Teilmenge der Ergebnisse abzurufen, bietet dies eine signifikante / spürbare Verbesserung?
mysql
performance
join
Jim
quelle
quelle
LIMIT
die Effizienz verbessern: Optimieren von LIMIT-AbfragenAntworten:
Wenn Sie
LIMIT
die Leistung verbessern möchten , benötigen SieLIMIT
vorJOIN
Diese Prinzipien können einen langen Weg gehen, wenn Sie sie orchestrieren können.
Ich habe diese Konzepte gelernt, indem ich mir dieses YouTube-Video angesehen habe (hör dir den französischen Akzent genau an).
Ich habe diese Konzepte verwendet, um eine sehr schwierige StackOverflow-Frage zum Abrufen der 40 wichtigsten Artikel aus einigen Tabellen zu beantworten: 12. Mai 2011: Abrufen einer einzelnen Zeile aus der Join-Tabelle .
In meiner Antwort auf diese Frage (16. Mai 2011) habe ich die folgende Abfrage geschrieben und gründlich getestet:
Bitte beachten Sie die Zeile in der Abfrage mit dem
LIMIT
Diese Unterabfrage ist drei Ebenen tief vergraben. Dadurch konnte ich die letzten 40 Artikel verwenden
LIMIT
. Danach habe ich die notwendigen JOINs durchgeführt.GEWONNENE ERKENNTNISSE
LIMIT
Durchführen von Unterabfragen ist aufgrund der Kardinalität der Indizes, des Dateninhalts und der Größe der Ergebnismenge aus dem möglicherweise nicht immer die AntwortLIMIT
. Wenn Sie alle Ihre "Enten in einer Reihe" haben (beachten Sie die vier Prinzipien für Ihre Abfrage), können Sie überraschend gute Ergebnisse erzielen.LIMIT
indem Sie nur Schlüssel sammeln.quelle
(A [LEFT] JOIN B) LIMIT 100
ist gleichbedeutend mit(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Wo[LEFT] JOIN
bedeutet äußere oder innere Verbindung(A LIMIT 100) [LEFT] JOIN B
. Die Idee ist,LIMIT
die Größe der Ergebnismenge so früh wie möglich zu bestimmen. Ich benutze auchLEFT JOIN
stattINNER JOIN
weilLEFT JOIN
wird die Reihenfolge der Tasten auf der linken Seite beibehalten.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
können normalerweise umgeschrieben werden als(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(kein INNER JOIN hier, mit inneren Verknüpfungen wären sie nicht gleichwertig.) Rolandos Beispiel ist genau ein solcher Fall.Wenn eine Abfrage ausgeführt wird, wird sie zuerst in einen Plan übersetzt, der aus mehreren Operatoren besteht. Es gibt zwei grundlegende Arten von Operatoren: Blockieren und Nichtblockieren. Ein nicht blockierender Operator ruft für jede von ihm angeforderte Zeile eine Zeile (oder einige Zeilen) von seinem Kind oder seinen Kindern ab. Ein Blockierungsoperator muss dagegen den gesamten Zeilensatz aller seiner untergeordneten Elemente einlesen und verarbeiten, bevor er eine Ausgabe erzeugen kann.
Sortieren ist ein typischer Blockierungsoperator. Eine Auswahl mit Bestellung von profitiert also nicht viel von einem Limit. Es gibt jedoch RDBMS, die einen Sortieralgorithmus verwenden können, der weniger Speicher benötigt und schneller ist, wenn eine Limit-Klausel bereitgestellt wird. In diesem Fall reicht es aus, nur die aktuell ersten n Zeilen zu speichern und sie aus dem Speicher zu verschieben, wenn frühere Zeilen hinzukommen. Das kann ein erheblicher Leistungsgewinn sein. Ich bin mir jedoch nicht 100% sicher, ob MySQL diese Fähigkeit besitzt.
In beiden Fällen muss auch eine Limit-Sortierung noch den gesamten Eingabezeilensatz verarbeiten, bevor die erste Ausgabezeile erstellt werden kann. Wenn dieser Algorithmus implementiert ist, kann er die Sortierung beschleunigen. Wenn der Rest der Abfrage der teuerste Teil ist, wird sich die Gesamtausführungszeit aufgrund eines vorgegebenen Grenzwerts nicht wesentlich verbessern.
quelle
GROUP BY
dies möglicherweise zu einem Plan führen, der keine blockierenden Operatoren enthält.In meinem Fall kann ich ja sagen , auch wenn ich (noch) nicht verstehe warum.
Beachten Sie die Zeit: 18 Sekunden. Gleiche Anfrage mit einem großen Limit:
Mehr als zehnmal schneller !!!
EXPLAIN geben für beide Anfragen das gleiche Ergebnis.
LIMIT sollte nur stören, um die Ergebnismenge zu begrenzen (dh wenn ich LIMIT 4 mache, bekomme ich nur die ersten 4 Zeilen der obigen Ergebnismenge).
quelle
LIMIT
. Ihre erste Abfrage wird in 18 Sekunden ausgeführt und ergibt eine Ergebnismenge. Alle Daten in der 2. Abfrage werden aufgrund der ersten Abfrage bereits im InnoDB-Pufferpool zwischengespeichert. Natürlich muss die 2. Abfrage schneller sein. Auch wenn Sie MySQL neu starten, führen Sie die 1. Abfrage aus, starten Sie MySQL neu und führen Sie die 2. Abfrage aus Abfrage erhalten Sie das gleiche Ergebnis. . Ein besseres Ergebnis fürLIMIT
kann nur durch Folgendes erzielt werden : 1)LIMIT
vorherJOIN
, 2) LIMIT in SortierreihenfolgeASC
oderDESC
.