Performance-Steigerung durch “Expression Index” in Firebird
Nachdem ich gestern versucht habe, die Performance einer MySQL-Webanwendung zu verbessern, geht es heute um eine C++-Anwendung, die auf einer Firebird-Datenbank basiert. Auch hier galt es den Flaschenhals zu finden, der eine bestimmte SQL-Abfrage stark ausbremste. Wie so oft handelte es sich um eine Programmfunktion, die bereits einige Jahre auf dem Buckel hat und die erst mit der Zeit, also mit zunehmenden Datenmengen, (Performance-) Probleme bereitet.
Die entsprechende SQL-Anweisung war schnell gefunden. Sie war (vereinfacht) wie folgt aufgebaut:
SELECT * FROM tabelle a JOIN tabelle b ON (UPPER(a.username) = UPPER(b.username))
Es waren in Wirklichkeit mehrere JOINS beteiligt. Erste Tests ergaben jedoch, dass der JOIN über den Usernamen für die schlechte Performance verantwortlich war. Das UPPER() ist notwendig, da in den beiden Tabellen Groß- und Kleinschreibung (durch Usereingaben) vermischt wurden (nicht fragen warum, ist so!!).
Als erstes kam ich auf die Idee, einen Index auf die Spalte “username” zu setzen, um den JOIN zu beschleunigen. Leider jedoch ohne Erfolg. Durch das UPPER() bleibt der “normale” Index wirkungslos.
Firebird bietet seit Version 2.0 die Möglichkeit, einen so genannten Expression Index zu verwenden, d.h. einen Ausdruck statt einer konkreten Spalte. Erzeugen lässt er sich wie folgt:
CREATE INDEX idx_username ON tabelle COMPUTED BY (UPPER(username));
Das Resultat war eine Steigerung der Performance um ein Vielfaches (ca. Faktor 10)!
Sicherlich lässt sich ein Expression Index noch für andere Einsatzzwecke nutzen. Besonders hilfreich ist er jedoch, wenn man ein VARCHAR-Feld “case insensitive” durchsuchen möchte oder zwei Tabellen über VARCHAR-Felder “joinen” will / muss, wo Groß- und Kleinschreibung keine Rolle spielen soll.
verfasst von Michael am 27. August 2010 um 14:51
vorheriger Artikel: Warum Views böse sind…
nächster Artikel: T-Mobile liefert Android 2.2 Froyo für das HTC Desire aus – geht doch!

