MySQL unterstützen

Oft hat man das Problem, dass man unbedingt möchte, dass ein bestimmter Index genutzt wird. Hat man die Tipps im letzten Beitrag befolgt und der Index wird laut EXPLAIN-Befehl immernoch nicht benutzt, wundert man sich. Als nächster Schritt wird brachiale Gewalt angewendet, indem man FORCE INDEX benutzt, damit auch garantiert der gewünschte Index genutzt wird. Aber MySQL verweigert weiterhin. Warum nur? Weil die SELECT-Anfrage genau das verhindert! Ich möchte hier ein paar typische Fehler aufzeigen und wie man es besser macht, damit Indizes überhaupt genutzt werden können und die Abfragen erheblich schneller abgearbeitet werden können.

Problem: Wir möchten Datensätze finden, an deren Anfang der String ‚Auto‘ steht (beispielsweise Automobil, Auto, Automat).
Schlecht:

SELECT *  FROM tabelle  WHERE spalte LIKE 'Auto%'

Problem ist hier, dass auf Funktionen kein Index angewendet werden kann. Wenn man allerdings eine Suche mit LIKE durchführt, kann ein Index sehr wohl benutzt werden – das geht allerdings nur, wenn man mit LIKE den Wortbeginn festlegt. Bei LIKE ‚%Auto%‘ kann wiederum kein Index genutzt werden. Das ist in der Natur binärer Suchbäume begründet.

Achtung, wichtige Regl: In einem Index gespeicherte Werte können darüber Auskunft geben, welche Werte in einer Spalte vorhanden sind, er weiß allerdings nicht, welche Werte in der Spalte nicht vorhanden sind!
Schlecht:

SELECT *  FROM tabelle  WHERE spalte!=0

Damit für eine solche Abfrage ein Index benutzt werden kann, müssen wir die Werte einbeziehen, die es gibt:

SELECT *  FROM tabelle  WHERE spalte>0  -- AND spalte<0

Die zweite Bedingung ist abhängig davon, ob es sich bei der Spalte um einen UNSIGNED INT (oder Float) handelt oder nicht.

Eine arithmetische Rechnung kann ebenfalls nicht für einen Index genutzt werden. Deshalb schlecht:

SELECT *  FROM tabelle  WHERE menge + 3000 < 5000

Besser ist es, bereits in der Anwendung bzw. vor der Query die Ungleichung sozusagen in die Variable (die Tabellenspalte) und die Konstante zu zerlegen und somit als performantere Variante folgendes zu nutzen:

 SELECT *  FROM tabelle  WHERE menge < 2000

Außerdem kann ein Index nicht verwendet werden, wenn auf beiden Seiten einer Bedingung eine Spalte (kann auch die gleiche sein) derselben Tabelle verwendet wird. Das ist allerdings nicht immer ganz leicht zu umgehen.
Zu diesem Punkt fällt mir leider gerade kein praxisnahes Beispiel ein.

Was in anderen DBMS als MySQL durchaus zu Problemen führen kann, ist die Verwendung von unterschiedlichen Datentypen beim Vergleich. Wenn die Spalte vom Typ INT ist und man per WHERE spalte='123' abfragt, kann mitunter der Index nicht benutzt werden, da 123 als String zum Vergleich übergeben wurde. Bei MySQL ist das aber kein Problem, da es einen automatischen Cast vornimmt und somit WHERE spalte=123 ausführt.

Ich hoffe nun können sie sich wieder mit ihrer Datenbank anfreunden, die manchmal ganz störrisch verweigert, einen bestimmten Index einzusetzen ????


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0