oliver: [mySQL] Tuning eines SELECT-Statements

Beitrag lesen

[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.

  1. 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.

  2. 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