theHacker

sieht vor lauter Ads den Content nicht mehr
Teammitglied
ID: 69505
L
20 April 2006
22.680
1.315
Moin.

Mal ne Frage an die MySQL-Profis hier:
Bringt es einen Nutzen, wenn ich an jede SELECT-Query LIMIT 1 setze, wo ich nur einen Datensatz brauche?

Das Manual spricht:
As soon as MySQL has sent the required number of rows to the client, it aborts the query unless you are using SQL_CALC_FOUND_ROWS.
Quelle: https://dev.mysql.com/doc/refman/5.0/en/limit-optimization.html

Schon klar. Aber gilt das auch bei einer Selektion nach einem Primär- oder Unique-Schlüssel? Oder is MySQL da so clever und bricht automatisch ab, sodass ich mir den Zusatz sparen kann?
 
Bei der suche nach eines einzigartigen Datensatzes also Suche nach nur einem Primary Key oder Unique Key erkennt der Query Optimizer dies und führt sozusagen selbst einen Limit 1 aus, dies kannst du leicht durch ein Explain-Statement ausprobieren.
 
[...] dies kannst du leicht durch ein Explain-Statement ausprobieren.
Und wie seh ich das?
Code:
[FONT=Courier New][B][COLOR=#9932cc]EXPLAIN[/COLOR][/B]
[B][COLOR=#9932cc]SELECT[/COLOR][/B] * [B][COLOR=#9932cc]FROM[/COLOR][/B] [B][COLOR=#9932cc]table[/COLOR][/B]
[B][COLOR=#9932cc]WHERE[/COLOR][/B] primary_key = 1
[B][COLOR=#9932cc]LIMIT[/COLOR][/B] 1;[/FONT]
und
Code:
[FONT=Courier New][B][COLOR=#9932cc]EXPLAIN[/COLOR][/B]
[B][COLOR=#9932cc]SELECT[/COLOR][/B] * [B][COLOR=#9932cc]FROM[/COLOR][/B] [B][COLOR=#9932cc]table[/COLOR][/B]
[B][COLOR=#9932cc]WHERE[/COLOR][/B] primary_key = 1;[/FONT]
liefern ja dasselbe: Primärschlüsselzugriff, Rows 1, logisch.
 
die Rows sind nicht die echten Zeilen, die es liest, sondern was MySQL vermutet ;)
Und wenn es vermutet nur eine Zeile, dann wird es wohl den unique Datensat-"Constraint" erkannt haben.
 
Warum nicht einfach mal testen ? =)

50 000 Abfragen auf 50 Durchgängen (Durchschnitt genommen). Einmal mit LIMIT 1 einmal ohne. ^^

Ergebnis:
Durchschnitt (ohne limit): 2.4 Sekunden / 50 000 Abfragen
Durchschnitt (mit limit): 2.3 Sekunden / 50 000 Abfragen

Also bewirkt es wohl nicht wirklich was x)

Aber um sicher zu gehen, nochmal den Test:
Durchschnitt (ohne limit): 2.6 Sekunden / 50 000 Abfragen
Durchschnitt (mit limit): 2.8 Sekunden / 50 000 Abfragen

Wir sind jedoch auf Arbeit dazu verpflichtet, dieses LIMIT 1; dennoch zu benutzen um den anderen Leuten die Übersicht zu erleichtern. Sprich, dass sie anhand der Abfrage sofort sehen, dass dieses result nur ein row haben kann. ^^
 
Zuletzt bearbeitet:
Toll, wie sinnlos, dann arbeitet mal zwischendurch nen anderer Prozess auf der Platte oder mit der CPU und es treten falsche Messdaten auf.

denn ohne Limit und mit Limit equivalent, wie du nämlich anhand deiner Messdaten siehst wiedersprechen sich beide Ergebnisse, also hat irgendwas anderes da noch mit ringefunkt.

Die Leistung mit und ohne Limit ist genau gleich
 
Die Leistung mit und ohne Limit ist genau gleich

Öhm, er sagt doch gar nichts anderes, oder?
Und der Test mag doch sinnvoll sein, wenn man große zeitliche Abweichungen messen kann..

Naja, und die Praktik immer ein LIMIT 1 da ran zu hängen schadet sicherlich nicht.. erhöht jedenfalls die Lesbarkeit.
 
Naja, und die Praktik immer ein LIMIT 1 da ran zu hängen schadet sicherlich nicht.. erhöht jedenfalls die Lesbarkeit.
Sowas wollt ich hören ;)
Und der Test mag doch sinnvoll sein, wenn man große zeitliche Abweichungen messen kann..
Mit dem Wissen, wie die DB arbeitet, zu argumentieren bringt aber mehr, als nur schnell ein paar Benchmarks laufen zu lassen.
Und bei so einer Frage, wie ich sie gestellt hab, bin ich nicht davon ausgegangen, dass falls es Unterschiede macht, diese bei normalen Datenmenge überhaupt messbar sind.
 
Mit dem Wissen, wie die DB arbeitet, zu argumentieren bringt aber mehr, als nur schnell ein paar Benchmarks laufen zu lassen.
Und bei so einer Frage, wie ich sie gestellt hab, bin ich nicht davon ausgegangen, dass falls es Unterschiede macht, diese bei normalen Datenmenge überhaupt messbar sind.


Mit der richtigen Anzahl an Tests ist alles messbar ;)
 
Toll, wie sinnlos, dann arbeitet mal zwischendurch nen anderer Prozess auf der Platte oder mit der CPU und es treten falsche Messdaten auf.

denn ohne Limit und mit Limit equivalent, wie du nämlich anhand deiner Messdaten siehst wiedersprechen sich beide Ergebnisse, also hat irgendwas anderes da noch mit ringefunkt.

Die Leistung mit und ohne Limit ist genau gleich

Genau das habe ich doch da oben gemeint ;) So mit der minamalen Prozessanzahl unter Debian und einem Quadcore (Der sollte genug luft haben ;)), lagen die Sekunden bei beiden mit 2.3 gleich ^^ Weil wäre da wirklich ein Unterschied gewesen, wäre dieser bei den Datenmengen mehr als nur auffällig und im oberen Beispiel auch nicht wiedersprüchlich.

Aber wie bereits oben geschrieben, sind wir dazu verpflichtet dieses zur verbesserterten Lesbarkeit zu benutzen ^^
 
Mit der richtigen Anzahl an Tests ist alles messbar ;)
Um solche Tests zu erstellen brauchst du aber genau das Wissen der DB-Interna ;)
Denn sonst haste mal schnell nen Szenario erschaffen, welches Full-Table-Scans priorisiert und du entscheidest dich falsch zu einer DB-Struktur die eben ohn eFull-Table-Scan durchgeführt wurde weil die Daten etwas anders waren oder die Indexe etwas anders was wieder zu anderen Zeiten führt.
Also ich verlasse mich lieber da genau über das was ich alles von den Internas der MySQL-Engine weiß und muss das teilweise korrigieren, wenn es Fehler in MySQL gibt oder bestimmte Dinge nicht rchtig implementiert sind (wie vor einiger Zeit die Subquerys im frühen MySQL 5)

lagen die Sekunden bei beiden mit 2.3 gleich ^^
neija bei deinem Test waren aber die Antwortzeiten verschieden, mal mit Limit besser mal ohne besser, daraus kann man keinen Rückschluss führen, dass sich nun beides nichts gibt. Da es auch wieder abhängig von Datenmengen oder ähnlichem ist, es können sich 2 Szenarien sehr ähnlich verhalten, wenn die Menge an Datensätzen gering ist und somit die Lookups der KEys schnell sind. Lieber informieren wie die Engine das wirklich handhabt als einen möglicherweise falschen Test ausführen und Halbswahrheiten verbreiten (war jetzt hier nicht so, aber kann schnell passiern)