[mySQL] Tuning eines SELECT-Statements
oliver
- datenbank
[mySQL] Tuning eines SELECT-Statements
OK, das Problem das ich habe, hat nichts mit Wurst zu tun, aber ich
versuche es mal so zu beschreiben:
Es ist, als ob man in den Supermarkt geht um eine Wurst zu kaufen,
aber die gesamte Fleischtheke mit nach Hause nehmen muss, um dort
alles wegzuschmeissen bis nur noch die Wurst übrigbleibt.
In einer Tabelle der Datenbank stehen SQL-Statements, die von
einem PHP-Script ausgelesen werden. In diesen Statements erfolgt ein
Join über drei Tabellen, das Ergebnis wird sortiert (ORDER BY) und
auch mengenmässig begrenzt (LIMIT), wobei die Ergebnisse nur in
Ausnahmefällen ab der ersten Zeile zurückgegeben werden.
Diese Statements werden also von meinem Script eingelesen und
wieder an die Datenbank abgefeuert. Ich brauche aber nur einen
Bruchteil der zurückgelieferten Ergebnisse, etwa 5%, die aus diesen
Ergebnissen zufällig ausgewählt werden. Bisher erfolgt diese Nach-
Auswahl per PHP, d.h. es werden zunächst alle Ergebnisse an PHP
übermittelt (die ganze Fleischtheke eben).
Wegen ernsthafter Performance-Schwierigkeiten suche ich da jetzt
eine bessere Lösung, die insb. die DB entlasten sollte.
Hier ein paar Ideen von mir wie es besser gehen KÖNNTE, die aber
ALLE NICHT FUNKTIONIEREN, bzw. wegen der Rahmenbedingungen keinen
Sinn ergeben:
SUBSELECT: Scheidet zum einen aufgrund der verwendeten mySQL-
Version aus, würde den DB-Server zudem nur zusätzlich belasten
(ORDER BY RAND() ist bei grossen Datenmengen tödlich)
Der SELECT-String könnte verändert werden, z.B. ein ORDER BY RAND
eingefügt und dann das LIMIT so verändert werden, das man nur noch
die Anzahl der tatsächlich benötigten Zeilen erhält. GEHT BEIDES
NICHT. Sowohl das ORDER BY RAND(), als auch eine Veränderung des
LIMIT hätte die Folge, das die zurückgegebenen Daten andere sind
als die, welche die Selektion ursprünglich betraf.
CREATE TEMPORARY TABLE: Würde zwar funktionieren, aber nicht
wirklich einen Performancegewinn bringen (siehe subselect)
Statt einer temporäreren Tabelle eine dauerhafte Tabelle
generieren, damit diese nicht bei jedem Aufruf neu generiert
werden muss. Macht auch keinen rechten Sinn. Redundante
Datenhaltung (z.T. die selben Daten in zehn verschiedenen
Tabellen) und x-hunderte von Tabellen wären die Folge.
Irgendwelche Ideen?
:)
gruss oliver
Hi,
wenn Du beispielsweise einen Primaerschluessel vom Typ 'integer' haettest, der fortlaufend hochzaehlt, dann haette ich einen Vorschlag zu machen.
Gruss,
Lude
---
"Harald Schmidt, wo bist Du?"
Hi,
wenn Du beispielsweise einen Primaerschluessel vom Typ 'integer' haettest, der fortlaufend hochzaehlt, dann haette ich einen Vorschlag zu machen.
hm, so eine id ist vorhanden, fortlaufend kann man so und so sehen; ist halt ein auto-increment-feld, und in der entsprechenden Tabelle stehen ja auch noch andere Datensätze, die das ursprüngliche Statement nicht selektiert. Nur in Bezug auf die Selektion sind die IDs dann nicht durchlaufend.
Aber lass doch mal bitte höhren, ich bin ja für jede Anregung dankbar :)
gruss oliver
Hi,
[...]
was willst Du erreichen? Um was geht es ueberhaupt?
- In einer Tabelle der Datenbank stehen SQL-Statements, die von
einem PHP-Script ausgelesen werden. In diesen Statements erfolgt ein
Join über drei Tabellen, das Ergebnis wird sortiert (ORDER BY) und
auch mengenmässig begrenzt (LIMIT), wobei die Ergebnisse nur in
Ausnahmefällen ab der ersten Zeile zurückgegeben werden.
Du hast "n" SQL-Statements in einer Tabelle fuer SQL-Satetements und jedes Statement JOINed ueber drei Tabellen?? Und was mit vertikaler Filterung?
- Diese Statements werden also von meinem Script eingelesen und
wieder an die Datenbank abgefeuert. Ich brauche aber nur einen
Bruchteil der zurückgelieferten Ergebnisse, etwa 5%, die aus diesen
Ergebnissen zufällig ausgewählt werden. Bisher erfolgt diese Nach-
Auswahl per PHP, d.h. es werden zunächst alle Ergebnisse an PHP
übermittelt (die ganze Fleischtheke eben).
Kriterien?
[...]
Brich es mal fuer die ganz Doofen etwas herunter, bitte.
Gruss,
Lude
---
"Wenn der Wind von dorther ueber die Felder weht, dann weiss ich es wird Sommer."
Hi Lude,
was willst Du erreichen?
eine performantere Anwendung ;)
Um was geht es ueberhaupt?
Also, um was es geht lässt sich nicht so einfach sagen, ich habe fast eine Stunde gebraucht um das Problem so zu abstrahieren und darzustellen, wie ich das oben getan habe.
Kurz gesagt geht es bei der Konstruktion mit den SQL-Statements in der Tabelle darum, komplexe Zusammenhänge möglichst flexibel handeln zu können. Bloss performant muss das ganze eben auch noch sein... :)
Und was mit vertikaler Filterung?
Hä? Versteh ich nicht.
Kriterien?
Zufall :)
ein ORDER BY RAND() könnte es tun, ist aber bei den Datenmengen tödlich...
gruss oliver