Hallo Alle,
ein Problem mit den ganzen Vorschlägen die hier veröffentlicht werden ist, dass es alles immer Schrotschüsse sind in der Hoffnung etwas zu treffen und dass Kollateralschäden billigend in Kauf genommen werden.
Soll heissen nicht jeder Index ist für jeden Shop gut, der eine hat wenig Produkte mit vielen Varianten (Typisch bei Bekleidung) der andere viele Produkte ohne Varianten.
Also ich versuch mich jetzt mal an einer einfachen Erklärung wo ein Index gut tut und wo man sich orientieren kann.
Zuerst mal was ein paar Worte zur Einführung wie funktioniert eine Datenbank.
-Profis bitte nicht totlachen-
Stellt euch eine Datenbank einfach vor wie einen Ordner und jeder Datensatz ist ein Blatt Papier, wenn ich einen Datensatz einfüge lege ich einfach das Blatt oben in den Order, (ist schön schnell)
Jetzt suche ich etwas, dazu muss ich -ohne Index- den Order von vorne bis hinten durchblättern und jedes Blatt ansehen d.h. im Durchschnitt muss ich den halben Ordner durchblättern bis ich den gewünschten Datensatz finde .
Ein Index ist ein Inhaltsverzeichnis, also im meinem Beispiel ein Deckblatt oben auf, auf dem steht an welcher Stelle ich den gewünschten Datensatz finde, so weit so schön, aber so einen Index zu verwalten macht Arbeit, da er jedes mal wenn ein Datensatz eingefügt, gelöscht oder verändert wird aktualisiert werden muss, für mein Blatt Papier heisst dass dass wenn ich den neuen Eintrag nicht zwischen zwei vorhandene quetschen kann, ich das ganze Blatt wegwerfen muss und neu schreiben, das kann die Datenbank stark belasten (entgegen meinem Beispiel ist übrigens das sortierte Einfügen von Daten ein Horror für einen Index, wer mehr wissen will sollte sich mit B-Tree oder Bayer Bäumen beschäftigen).
Wie entscheidet die Datenbank ob sie einen Index verwendet zuerst liest sie die Verwaltungsinformationen, sucht welche Indexe passen würden bzw verwendet werden können, dann prüft sie die Selektivität (Kardinalität) des Indexes und entscheidet (mit begrenzter Intelligenz) ob er verwendet wird oder nicht Beispiel die Kundennr im Kundenstamm ist einmalig (unique) und hat damit die bestmögliche Selektivität auf der anderen Seite ist z.B. das Land aus dem Kunden kommen das dürften meist wenige verschiedene sein und weisst deshalb eine geringe Selektivitaet aus.
Wer mehr wissen will kann sich von MySQL mit dem "explain" Befehl sagen lassen welche Indexe bei welcher Abfrage verwendet werden.
- jetzt die Hardwareseitigen Probleme -
MySQL speichert Daten und Indexe in separaten Dateien, d.h. jedes mal wenn ein Index verwendet wird muss eine extra Datei geöffnet werden. -das ist langsam-
Daten von der Platte lesen ist langsam, Daten im Hauptspeicher sind schnell verarbeitet .
Festplatten sind in Clustern organisiert, wenn also Daten von der Platte gelesen werden dann wird immer mindestens ein ganzer Cluster von der Platte in den Speicher geladen, egal ob Daten oder Index (üblicherweise 4 KB)
also DatenTabelle öffnen,
Index entscheiden
Index(e) öffnen
Index einlesen, auswerten
zurueck zu den Daten
Datensatz anfahren und einlesen
-viel Arbeit-
also wann lohnt der Index
phpMyAdmin liefert alle notwendigen Informationen zur Datenbank bei Speicherplatzverbrauch
einfach die Tabelle aufrufen und ansehen.
Beispiel Products: bei 73 Produkten sind das 9 KB, da bringt ein Index nix.
(er kann aber notwendig sein um Unique constraints zu verwalten)
Hier mal ein abschreckendes Beispiel:
Tabelle products_options_values_to_products_options
Zeilen 946
Speicherplatzverbrauch Typ Verbrauch
Daten 12,298 Bytes
Index 23,552 Bytes
Insgesamt 35,850 Bytes
Hier ist der Index doppelt so groß wie die Daten also ein echter Performance Killer
XT(C|M) bietet die Möglichkeit die Querys mit Laufzeit zu speichern, also bevor Ihr da wie verrückt Indexe erstellt die den Shop runter ziehen erst auswerten und um euch den Tag endgültig zu verderben, ein Index kann die eine Abfrage beschleunigen und die andere ausbremsen das kann man umgehen indem man die Abfrage umschreibt .
Einen Index kann man vermeiden indem man ihn in eine Berechnung einbezieht .
z.B. aus:
SELECT * FROM tabelle WHERE feld=1
macht man:
SELECT * FROM tabelle WHERE feld+0=1
dann wird der (Performance-)Killerindex nicht verwendet
so und jetzt rufen Staubsauger und Küche -
schönen Sonntag