Ein relationales System ist nicht notwendigerweise langsamer

Die System-Performance hängt sehr stark vom Anwender ab

26.04.1991

Obwohl DB2 schon seit 1985 auf dem Markt ist, sind große operative Anwendungen mit dem relationalen Datenbanksystem der IBM noch immer eine Seltenheit. Einer der Gründe dafür ist die Unsicherheit über die DB2-Performance und den dafür notwendigen Hardwarebedarf. Dabei ließe sich die Zugriffegeschwindigkeit weitgehend vom Anwender beeinflussen.

Von Chris Date, einem der Verfechter des Relationenmodells, stammt die Aussage, daß "ein relationales DBMS nicht modellbedingt eine schlechtere Performance als ein konventionelles haben muß". Entscheidend für das Leistungsverhalten eines relationalen DBMS, so seine Aussage, seien vielmehr "nur die technische Implementierung des DBMS und die Fähigkeit des Optimizers."

Ganz so einfach ist die relationale Wirklichkeit dann allerdings doch nicht. Wenn man als Performance die CPU-Zeit und die I/O-Operationen bezeichnet, die zur erfolgreichen Durchführung einer Datenbankoperation benötigt werden, so kann man folgende Sachverhalte konstatieren:

I/O-Aufwand: Die Anzahl der Zugriffe in einem relationalen DBMS muß nicht höher als bei konventionellen DB-Systemen sein, da in relationalen Datenbanken die gleichen Speicherungsverfahren und Zugriffsalgorithmen implementiert sein können. Allerdings müssen relationale Systeme ebenfalls einen Reifeprozeß im praktischen Einsatz mitmachen, bis alle Techniken ausgefeilt sind. So wurde zum Beispiel erst in der DB2-Version 2.2 die Index-Schnittmengen-Technik ("Multiple Index Access Path") eingebaut, über die ein "Alt-DBMS" wie Adabas schon seit 1971 verfügt.

CPU-Aufwand: Ähnlich wie bei einem Auto, wo der Komfort eines automatischen Getriebes mit PS-Einbußen bezahlt werden muß, kostet der höhere Grad an Automatik bei relationalen Datenbanksystemen ebenfalls mehr CPU-Zeit. Die Pfadlänge, das heißt die Anzahl der für eine Datenbankoperation benötigten Instruktionen, ist eindeutig größer als bei konventionellen DB-Systemen. So hatte zum Beispiel der IBM-Mitarbeiter Chris Loosley bei Vergleichsmessungen für DB2 einen durchschnittlichen CPU-Bedarf von 163 Prozent gegenüber IMS ermittelt. Selbst wenn DB2 zwischenzeitlich verbessert wurde, durfte dennoch ein CPU-Mehrbedarf verblieben sein. Bedingt durch die inzwischen schnelleren Prozessoren schlägt dieser aber nicht mehr so merklich auf die Antwortzeit durch.

Die zweite Aussage von Chris Date, daß nämlich die Leistungsfähigkeit des Optimizers für die Performance verantwortlich sei, ist nur teilweise richtig. Zwar ermittelt ein Optimizer den günstigsten Befehlsablauf für ein SQL-Statement unter Berücksichtigung der vorhandenen Datenbankstruktur, doch gilt dies immer nur für einen einzelnen SQL-Befehl; er kann nicht die SQL-Folge innerhalb eines Programmes optimieren. Das hat zur Folge, daß die Summe aller einzeln optimal aufgelösten Befehle doch zu einem in puncto Performance ungünstigen Ablauf führen kann.

Diese Erfahrungen haben inzwischen einige DB2-Anwender gemacht und daraus ihre Konsequenzen gezogen: Zum einen sollten durch eine Analyse der Antwort- oder Laufzeiten die kritischen Programme herausgefiltert und untersucht werden. So hat zum Beispiel die Alldata, das Rechenzentrum der Arag-Versicherung, nach der Einführung eines großen operativen Dialogsystems mit DB2 diesem Zweck eigens ein Tuning-Projekt gestartet.

Zum anderen sollten die Programmierer durch Verbesserung der Kenntnisse über die Datenorganisation und Arbeitsweise von DB2 in die Lage versetzt werden, Performance-Fehler vermeiden. So werden zum Beispiel bei der Colonia-Versicherung die Programmierer, nachdem sie SQL gelernt und angewendet haben in einem internen Performance-Kurs vertiefend geschult.

SQL-Kenntnisse allein reichen nicht

Im Gegensatz zu den DB-Anweisungen alter Systeme sollte SQL eigentlich so abstrakt und nicht-prozedural sein, daß ein Programmierer nichts über die Physik der Datenbank wissen muß. Der Optimizer, so die Theorie, kennt die Speicherorganisation der Datenbank und macht dann schon das Richtige aus dem SQL. Doch in der Praxis trifft dies nicht zu.

Nach Erkenntnissen, die aus den USA stammen, sind rund 60 Prozent aller Performance-Probleme bei DB2 auf die Anwendungen (SQL-Verwendung und Ablauflogik) zurückzuführen. Die restlichen Probleme hätten ihre Ursache im Datenbankdesign und in den Systemparametern. Ob diese Zahl auch für Europa und Deutschland zutrifft, ist meines Wissens noch nicht ermittelt worden; die Größenordnung ist allerding nicht unwahrscheinlich.

Die Performance von DB2 wird durch eine Reihe unterschiedlicher Faktoren beeinflußt. Betrachten wir zunächst das Datenbankdesign. Der Optimizer von DB2 wählt seine Zugriffsstrategie pro SQL-Befehl im wesentlichen aufgrund folgender Kriterien aus:

- Vorhandensein von Indizes auf den Tabellen,

- Ausprägungshäufigkeit der Werte in den Indizes (Kardinalität),

- Sortierung der Daten (Clustering) und

- Größe der Tabellen.

Somit kann der Datenbankadministrator (DBA) die Arbeitsweise beeinflussen durch:

- Einrichten oder Löschen von Indizes (speziell das Zusammensetzen eines Index aus mehreren Feldern kann sehr hilfreich wirken)

- Änderung der Sortierreihenfolge von Daten oder

- Reduzierung der Tabellenanzahl durch Denormalisierung (diese Maßnahme ist allredings kritisch, weil sie Änderungen der Programme zur Folge hat).

Wenn sich der Optimizer bei seiner Wahl des Zugriffspfades auf eine bestimmte Sortierung der Daten abgestützt hat, diese aber durch viele Zu- und Abgänge nicht mehr existiert, so ist die Performance ebenfalls gefährdet. Als Konsequenz ist bei DB2 eine regelmäßige Reorganisation notwendig. Mit weniger Aufwand läßt sich die Performance dagegen durch Änderung von Systemparametern beeinflussen. Speziell die Zugabe von Speicher wirkt Wunder.

Das DB-Design ist aber nur ein Faktor, der die Entscheidungen des Optimizers beeinflußt.

Der andere ist die Formulierung des SQL-Befehls. Leider stellt SQL keine eindeutige Sprache dar; ein und dieselbe Datenmenge läßt sich also durch unterschiedliche Formulierungen beschreiben.

Abbildung 1 zeigt beispielsweise drei alternative SQL-Befehle für die gleiche Selektion. Inzwischen ist der DB2-Optimizer so intelligent, daß er in diesem Beispiel für die Abwicklung der Befehle jedesmal den Index auf der Spalte KTO_NR - falls vorhanden - verwenden würde, so daß hier keine Performance-Unterschiede aufträten. Bei komplexeren Selektionsbedingungen kann das aber anders sein.

Die drei alternativen Formulierungen in Abbildung 2 führen allerdings zu unterschiedlichen internen Abläufen und damit zu unterschiedlicher Performance, da durch die prozedurale Form des zweiten und des dritten SQL-Befehls dem Optimizer eine bestimmte Arbeitsweise vorgegeben wird.

Welche Konsequenzen ergeben sich daraus? - Zunächst sollte der Programmierer stets die Formulierung verwenden, die dem Optimizer die Chance läßt, selbständig den Zugriffspfad auszuwählen. - Bei alternativen Möglichkeiten für die Selektionsbedingung ist immer diejenige zu bevorzugen, bei der DB2 wahrscheinlich von Indizes Gebrauch macht. Informationen hierzu enthält die DB2-Systemliteratur.

- Der Programmierer sollte sich durch Anwendung der Funktion EXPLAIN vergewissern, ob der Optimizer den wahrscheinlich richtigen Zugriffspfad ausgewählt hat. Um dies beurteilen zu können, muß der Programmierer erstens die Struktur der Datenbank kennen, zweitens über die Größenordnungen (Anzahl Zeilen und Pages) informiert sein und drittens die Arbeitsweise von DB2 verstehen.

Mögliche Maßnahmen bei einer ungünstigen SQL-Auflösung können entweder eine Anpassung des Datenbankdesigns oder eine Änderung des SQL-Statements sein. Diese Überlegungen gelten allerdings immer nur für ein einzelnes SQL-Statement; ungünstige Befehlsfolgen kann der Optimizer nicht erkennen.

Ein extremes Beispiel für falsche Befehlsfolgen ist das folgende: Ein gestandener IMS-Programmierer hatte in seinem DB2-Programm - wie er es von IMS her gewohnt war - die Daten zeilenweise abgeholt und diejenigen, die er benötigte, mit einer IF-Anweisung im Programm herausgefiltert. Da die Tabelle recht groß war, lief das Programm Stunden.

Machtlos gegen Programmierfehler

Mit einem einfachen Eingriff ließ sich die Laufzeit auf einen Bruchteil reduzieren: Die IF-Anweisung wurde durch eine WHERE-Bedingung im SELECT-Statement ersetzt. Dadurch änderte DB2 seine Arbeitsweise völlig: Statt des seriellen Durchlesens der Tabelle ("table Scan") verwendete das System gezielt Index-Zugriffe ("Matching Index Scan").

Vielleicht werden jetzt einige Leser sagen: So etwas macht man ja auch nicht!" Doch leider kommen solche Fälle in der Praxis vor. Der Grund ist mangelndes Hintergrundwissen über DB2 und seine Arbeitsweise; SQL allein genügt also nicht.

Auf einem Seminar berichteten Anwender, die DB2 in operativen Anwendungen einsetzen, über ihre Performance und Tuning-Erfahrungen. Dabei stellten sie übereinstimmend fest, daß die DB2 Funktion EXPLAIN nur eine geringe Hilfe für die Performance-Vorhersage bietet. Dafür wurden im wesentlichen drei Gründe genannt:

1 In operativen Anwendungsprogrammen werden üblicherweise keine komplexen SQL-Befehle verwendet. Einen gezielten Einzelsatz-Zugriff aber löst der Optimizer fast immer optimal auf.

2. Selbst Indikatoren für Performance-problematische Abläufe wie Table Scan, zusätzliche Sortierung und Merge Scan Join können völlig harmlos sein, wenn die Daten- oder Ergebnismenge klein ist.

3. EXPLAIN hilft nicht, ungünstige Befehlsfolgen zu entdecken.

Statt dessen ist es praktikabler, zunächst einmal das tatsächliche Performance-Verhalten der Programme abzuwarten und sie später erst zu tunen. Dann werden die zehn Transaktionen mit den längsten Antwortzeiten herausgefiltert und gezielt untersucht. Und manchmal stellt man dabei sogar fest, daß die Ursache der Probleme nicht bei DB2 zu suchen ist.