Von Matthias Jung auf Mittwoch, 07. April 2021
Kategorie: Data Management

Können Sie das mal übersetzen? Query Rewriting mit MySQL

Ab und zu kommt es vor, dass die eine oder andere Applikation ungünstig formulierte Statements an einen MySQL-Server schickt. Dies kann dann zu Performance-Problemen führen, da beispielsweise vom Optimizer ein ungünstiger Ausführungsplan generiert wird. Im besten Fall kann der Entwickler der Software dieses Problem schnell für einen Fix selbst lösen. In vielen Fällen, z.B. bei Kaufsoftware oder bei kompilierten Code, ist dies nicht so einfach möglich.

Flinte ins Korn?

In manchen Fällen kann hier auch der DBA eingreifen und mit dem Query-Rewrite-Plugin kurzfristig für Abhilfe sorgen.
Dazu muss dieses Plugin zunächst installiert werden. Die Datenbank liefert für diesen Zweck Skripte zur Installation und Deinstallation mit. Sie befinden sich im Ordner „share" unterhalb des Installationspfades der Datenbank.

Die Installation des Plugins kann anhand der folgenden Variable überprüft werden.

Befolge immer brav die Regeln!

Das Installationsskript aktiviert nicht nur das Plugin, sondern legt auch eine eigene DB „query_rewrite" an. In dieser befindet sich eine Tabelle „rewrite_rules", über welche das Regelwerk zum Umschreiben von Queries definiert werden kann.

X für ein U, bzw. U für ein D

Die Regeln werden über einfache „INSERTS" angelegt. Literale können dabei mittels eines „?" dargestellt werden.  Nehmen wir einmal an, dass wir aus bestimmten Gründen DELETE-Statements einer Applikation (MySQL Demo-Datenbank sakila) in UPDATE Statements umwandeln wollen.
In der Tabelle „sakila.customer" werden Kundendaten verwaltet. Kunden können aktiv (active = 1) oder inaktiv (active = 0) sein.
Hier ein exemplarischer Kundendatensatz aus der Tabelle.

Mittels der folgenden Regel möchten wir nun erreichen, dass ein DELETE-Statement in ein UPDATE-Statement gewandelt wird, welches das Feld „active" auf den Wert „0" setzt. Diese Regel legen wir wie folgt an:

Nach dem Erzeugen der Regel muss das Regelwerk mit dem folgenden Kommando neu geladen werden:

Versuchen wir nun einen Datensatz zu löschen und trifft der Hash-Wert unseres Kommandos auf den Hash-Wert unserer Regel (Spalte „pattern") zu, so wird die Query umgeschrieben.

Das Ergebnis ist wie erwartet. Der Kunde hat den Status inaktiv (active = 0).
Allerdings führen leichte Nuancen in den Queries bereits dazu, dass die Hash-Werte nicht mehr übereinstimmen. Im folgenden Beispiel wurde im DELETE-Kommando lediglich ein Spaltenname anderes definiert (CUSTOMER_ID).

Da die Hash-Werte nicht mehr identisch waren, wurde das Original-Statement ausgeführt. Der Datensatz wurde gelöscht.

Gehen Sie direkt auf Los, …

Es lassen sich aber auch andere Probleme mit diesem Plugin lösen. Im folgenden Beispiel hat ein Entwickler eine ungünstige WHERE-Klausel formuliert. Er nutzt die UPPER-Funktion auf der Spalte „title". Zwar sind alle Titel in der Tabelle „sakila.film" in Großschreibweise definiert, jedoch führt der Einsatz der Funktion dazu, dass der Optimizer den auf der Spalte angelegten Index nicht mehr nutzen möchte.

Dies kann bei einer großen Datenmenge zu einer erheblichen Laufzeitverlängerung führen. Auch dieses Problem kann über eine Rewrite-Regel behoben werden.

Wie zu erkennen ist, wurde die Regel nach dem Anlegen der Regel genutzt. Das Statement wurde in eine optimizer-freundlichere Form gebracht.

Fazit

Das Rewrite-Plugin kann an der einen oder anderen Stelle schnell Probleme lösen. Die Aktivierung kann online erfolgen. Für komplexere Regelwerke eignet es sich jedoch nicht wirklich. Hier gibt es verschiedene Proxy-Dienste, die deutlich mehr können. Diese sind jedoch nicht einfach im laufenden Betrieb einsetzbar und brauchen daher etwas länger in der Bereitstellung.

Kommentare hinterlassen