Frage an die Experten bezüglich Performance

alaninalanin

Mitglied
Hallo,

ich bin hier gerade in einer kleinen Diskussion darüber, in wieweit eine MySQL Tabelle geladen wird, wenn ich in einem Select ein Limit setze.

Z.B. ein SELECT t.spalte FROM table AS t ORDER BY Zeit DESC LIMIT 1

Dieser SELECT gibt mir ja am Ende genau ein Ergebnis aus. Allerdings würde mich interessieren ob MySQL im Zuge dessen die gesamte Tabelle laden muss, oder ob wirklich der letzte Datensatz geladen wird.

Im Prinzip müsste ja alles geladen werden, dann wird geordnet und am Ende nur ein Datensatz zurückgegeben.

Ist dem wirklich so und gibt es eventuell eine Möglichkeit dieses gesamte Laden irgendwie zu verhindern?

Vielen Dank für eure Antworten
Alanin // Jörg
 
Hallo,

da du immer den neuesten Eintragen bekommen möchtest könntest du einfach einen Index auf die Datumsspalte legen und dann eine Abfrage machen wie:
Select x,y,z from bubu where datum = max(datum);

Gruß Tom
 
Vielen Dank für deine Antwort

Jo, ist ne Möglichkeit - und SQL bricht dann die Abfrage ab, sobald das LIMIT erfüllt ist.

Ich muss das LIMIT setzten, da ich diese Abfrage in einem Subquery habe - und es möglich ist, dass die Zeit dann mehr als einmal zurückgegeben wird.

Das hier ist mein Query - er soll ein paar Daten für eine Forenübersicht auslesen. Hinzu nimmt er Die Thread- und Post-Tabelle und die Kunden-Tabelle für die Nicknames.

Ist bestimmt ein leichter Overkill an Subqueries. Sollte ich das ganze vielleicht noch optimieren und vielleicht den Kompromiss eingehen und Daten doppelt in der DB zu haben? Aber dafür wenige Subqueries?

Code:
SELECT f.ForumID,Name,Beschreibung,
	(SELECT COUNT(*) FROM forum_thread AS t
		WHERE t.ForumID = f.ForumID) AS thread,
	(SELECT COUNT(*) FROM forum_post AS p
		WHERE p.ForumID = f.ForumID) AS beitrag,
	(SELECT t.Name FROM forum_thread AS t
		INNER JOIN forum_post AS p ON (p.ThreadID = t.ThreadID)
		WHERE p.ForumID = f.ForumID
		ORDER BY p.Zeit DESC
		LIMIT 1) AS TName,
	(SELECT t.ThreadID FROM forum_thread AS t
		INNER JOIN forum_post AS p ON (p.ThreadID = t.ThreadID)
		WHERE p.ForumID = f.ForumID
		ORDER BY p.Zeit DESC
		LIMIT 1) AS TID,
	(SELECT p.PostID
		FROM forum_post AS p
		WHERE p.ForumID = f.ForumID
		ORDER BY p.Zeit DESC
		LIMIT 1) AS PID,
	(SELECT k.Nick
		FROM forum_post AS p
		INNER JOIN kunden AS k ON (k.KundenID = p.KundenID)
		WHERE p.ForumID = f.ForumID
		ORDER BY p.Zeit DESC
		LIMIT 1) AS Nick
	FROM forum_forum AS f
	WHERE KategorieID = '".db($kategorien[KategorieID])."' AND aktiv = 'Y'

Danke Jörg
 
Hallo,

soweit ich weiss kann MySQL bei LIMITS recht gut optimieren.
Lass dir nichtdestotrotz doch mal den Ausführungsplan anzeigen für dein Statement.

Mit EXPLAIN <sqlstatement> erhältst du eine Tabelle, in der du dann erkennst, ob z.B. Indizes benutzt werden können und wenn ja, welche usw.
Poste diesen dann noch mal bitte.

Select x,y,z from bubu where datum = max(datum);

Das wird so nicht funktionieren, da max() eine Gruppenfunktion ist. Ich denke du meintest das hier?

SQL:
Select x,y,z 
  from bubu 
 where datum = 
   (select max(datum) 
      from bubu 
     where ...)

Markus
 
Zuletzt bearbeitet:
Hallo nochmal,

ok,die Anzahl der Rows (letzte Spalte) ist recht gering. Daher können bei geringen Datensatzanzahlen je Tabelle (<10) Full Table Scans benutzt werden. Wieviele Datensätze hast du denn im Moment in deinem Forum?

Was auffällt, das er bei keiner anderen Tabelle ausser k und t versuchen würde, einen Index zu bemühen (Spalte key), und auch kein passender vorhanden ist (Spalte possible_key).

Dann haben wir noch 4x filesort durch das ORDER BY und 2x tempoary.

Fang am besten an, dir die Spalten in deiner WHERE und ORDER-BY-Klausel anzuschauen und einen passenden Index anzulegen und versuch das EXPLAIN erneut.


Werf dazu am besten mal einen Blick hier drauf:

http://dev.mysql.com/doc/refman/5.1/de/explain.html

und hier:

http://dev.mysql.com/doc/refman/5.1/de/order-by-optimization.html

Markus
 
Zuletzt bearbeitet:
im dem moment in dem ich den explain gemacht habe, waren gerade drei foren, ein thema und ein post in diesem thema vorhanden. ich bin gerade in der entwicklung des forums.

ich werde mit den index zeug rumspielen - vielen dank für deine hilfe

also wäre es vielleicht besser einen index auf die spalten zu legen, auf die ich abfrage? denn alle tabellen die hier benutzt worden haben einen index auf dem primary.
 
Hallo,

ja das macht auf jeden Fall Sinn.
Grad Spalten vom typ DATE o.ä. werden ja häufig beim Suchen (Bereichssuche o.ä.) oder Sortieren genutzt. (in deinem Beispiel war es glaub ich die Zeit-Spalte)
Aber auch die Spalten, über die du die Posts mit den Threads und die Threads mit den Foren verbindest, wären Kandidaten.

Das wirst du nur jetzt bei wenigen Daten noch nicht spüren, später jedoch auf jeden Fall.
Immer mal wieder ein EXPLAIN machen, dann siehst du, wie sich die Ausführungpläne aufgrund der Daten auch ändern können.

Markus
 
Zurück