oliver: [mySQL] Tuning eines SELECT-Statements

[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

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

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

  2. Hi,

    [...]

    was willst Du erreichen? Um was geht es ueberhaupt?

    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.

    Du hast "n" SQL-Statements in einer Tabelle fuer SQL-Satetements und jedes Statement JOINed ueber drei Tabellen?? Und was mit vertikaler Filterung?

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

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