phpbar.de logo

Mailinglisten-Archive

Abfrageoptimierung

Abfrageoptimierung

Andreas Müller mysql at universalware.de
Don Jun 15 13:16:56 CEST 2006


Hallo zusammen,

zu A. Kretschmer:
Falls du es nicht bemerkt hast ist dies hier eine MySQL Liste. D.h.
Diskussionen das andere RDBMS das ganz anders machen sind unsinnig. Es geht
hier um Lösungen für MySQL.

Nun gut dann zu Lösung. Die Antwort ist schon gefallen wenn auch nur als
Vermutung: Ein Index auf die Spalte.

Wo liegt nun eigentlich das Problem bei der Aufgabe?
MySQL muss in dem Fall einen full table scan durchführen. Da nun die
Datensätze so groß sind muss MySQL immer sehr viele Daten von der Platte
lesen bze. auf der Tabelle positionieren. Es sind zwar nur 150.000
Datensätze aber eben 1,5 GB Daten und das dauert.
Legt man nun einen Index auf die Spalte so verwendet der Optimizer
automatisch diesen Index weil er damit NICHT mehr auf die Datendatei
zugreifen muss denn die Werte die er addieren soll befinden sich ja bereis
im Index. D.h. es ist "billiger" einen full index scan zu machen als einen
full table scan.
Das ganze lässt sich so verallgemeinern:
MySQL liest nur dann Daten aus der Datentabelle wenn es Spalten benötigt die
es über einen gewählten Index nicht bekommt. In allen anderen Fällen
verwendet es die im Index gespeicherten Daten OHNE auf die Datentabelle
zurückzugreifen.
So können häufig verwendete Abfragen durchaus optimiert indem man an den
Zugriffsschlüssel einfach noch die Spalte(n) angängt die man aus den Daten
lesen will.

Im genannten Beispiel heisst das: Möchte ich eine performate Lösung haben um
die Summe von 'filesize' pro user_id zu ermitteln so kann ich zwar einen
einfachen Index auf 'user_id' verwenden - nur führt das zu Zugriffen auf die
Datendatei weil der Wert für 'filesize' gelesen werden muss. Lege ich einen
Index über 'user_id,filesize' an so erfolgt die Abfrag ausschließlich im
Index.

Es ist natürlich immer zu prüfen ob ein weiterer Index der Gesamtperformance
zuträglich ist oder eher nicht. Jeder Index mehr brenst unweigerlich INSERT
und DELETE sowei ggf. UPDATE. Man sollte auch prüfen welcher Index notwendig
ist und welcher nicht. Im Beispiel wäre ein Index auf 'user_id' und ein
weiterer auf 'user_id,filesize' ein Index zu viel. Der letztere würde in der
Regel ausreichen weil er auch für einen reine Selektion auf Basis user_id
ausreichend ist: MySQL kann von links Teilausdrücke in einem Index
verwenden.

Gruß,
Andreas


-- 
Infos zur Mailingliste, zur Teilnahme und zum An- und Abmelden unter
-->>  http://www.4t2.com/mysql 


php::bar PHP Wiki   -   Listenarchive