Datenbank
Performanz
4 Performanz


4.1 Einführung

Nach praktischen Erkenntnissen sind ca. 90% der Engpässe in der Performanz durch eine gute Planung und Umsetzung der Anwendung zu vermeiden

 

Die in diesem Kapitel angesprochenen Themen sollen die Performanz der Anwendung verbessern. Hierbei wird fast nur auf Techniken der Anwendung eingegangen. Es sollen nur wenige datenbankbasierten Tuningmaßnahmen aufgeführt werden.

 

Erst wenn die angesprochenen Maßnahmen umgesetzt wurden und die Anwendung immer noch zu langsam ist, sollte man sich mit datenbankabhängigen Tuningmaßnahmen näher beschäftigen.

 


4.2 Kritische Betrachtung von Performanz

Seien Sie niemals mit der erreichten Performanz zufrieden

 

Bei der Implementierung und dem Test der Anwendung sollten Sie schon kritisch auf die Antwortzeiten der Datenbank schauen. Schon hier kann man ungeschickte Abfragen aufdecken und frühzeitig gegensteuern.

 

In der Testphase hat man i.d.R. zuerst kleinere Datenbanken. Wenn hier schon Performanzengpässe zu beobachten sind, dann werden diese in der realen Anwendung erst recht zum Tragen kommen.

 


4.3 Protokollieren Sie die SQL Befehle

Protokolle der SQL Befehle können langsame Programmabschnitte aufdecken

 

Planen Sie in Ihrem Objektmodell eine weitere, direkte Zugriffsschicht für die Datenbank ein. In dieser können Sie dann bei Bedarf alle SQL Befehle in einer Textdatei (o.ä.) mit protokollieren. Diese können Sie bei Performanzengpässen dann entsprechend auswerten. Oft stellt sich so heraus, dass einige Abfragen zu oft oder ungeschickt formuliert sind. Sie können so die Engpässe schneller finden wie im reinen Debug-Modus der Anwendung.

 

Dieses Protokoll können Sie bei der realen Anwendung dann ausschalten.

 


4.4 Nutzung von Indizes

Indizes sind ein Feature, welches jede Datenbank unterstützt. Nutzen Sie es auch

 

Durch Indizes werden Datenbankabfragen enorm beschleunigt. Deshalb sollte man auf diesen Mechanismus nicht verzichten.

 

Aber erzeugen Sie nicht blind Indizes, nur um die Performanz zu verbessern. Überlegen Sie sich, welche Indizes Sie benötigen anhand der Abfragen, die Sie an die Datenbank stellen. Hierbei helfen Ihnen auch Datenbanktools (wie z.B. explain plan bei Oracle).

 

Die Verwaltung von Indizes (Anlegen und Verwalten von Bäumen) kostet selbst auch wieder Performanz. Es ist somit immer im Einzelfall zu verifizieren, ob ein Index sinnvoll ist oder nicht. Grundlage für diese Beurteilung spielen u.a. die Datenmengenabschätzung sowie die Selektivität der zu indizierenden Spalte.

 


4.5 Plausibilität schon auf Clientseite prüfen

Prüfen Sie die zu schreibenden Daten, bevor Sie diese in die Datenbank übertragen

 

Wenn Daten in die Datenbank geschrieben werden sollen, so können Sie auf der Clientseite vor dem Schreiben schon einige Plausibilitätsprüfungen durchführen, bevor Sie die Daten an die Datenbank weitergeben.

 

Die Datenbank muss die Daten vor dem Schreiben auf Konsistenz und Plausibilität prüfen. Wenn die Daten inkonsistent sind oder gegen eine Regel verstoßen, so wird die Datenbank einen Fehler zurückgeben. Dieser Mechanismus des Fehlerhandlings kostet viel Zeit und die Daten müssen von der Anwendung korrigiert und erneut übertragen werden.

 

Diesen Ablauf kann man schon im Vorfeld überprüfen und so die Datenbank entlasten.

 


4.6 Einsatz von IsNew / IsChanged

Beim Schreiben der Daten muss man unterscheiden, ob die Daten neu sind oder schon in der Datenbank eingetragen sind und ob die Daten überhaupt an die Datenbank übertragen werden müssen

 

Bei neuen Daten muss ein INSERT Befehl generiert werden, bei schon vorhandenen Daten wird ein UPDATE Befehl generiert. Häufig findet man Implementierungen, die zuerst ein INSERT Befehl absetzen. Wenn dieser dann fehlschlägt, wird ein UPDATE Befehl abgesetzt. Dies hat den Nachteil, das die Datenbank evtl. mehr Traffic hat als unbedingt notwendig ist.

 

Zur Unterscheidung kann im Objektmodell in den entsprechenden Klassen eine IsNew() Methode implementiert werden. Diese kann bei der Speicherungsmethode ausgewertet werden und ein entsprechender Befehl (INSERT / UPDATE) generiert werden.

 

Häufig werden Daten in die Datenbank geschrieben, ohne dass diese von der Anwendung geändert wurden. Hierfür kann eine IsChanged() Methode in den entsprechenden Klassen implementiert werden. Diese kann dann auch in der Speicherungsmethode ausgewertet werden. Wenn sich keine Daten geändert haben, so muss auch kein INSERT / UPDATE Befehl an die Datenbank abgesetzt werden.

 


4.7 Suchkriterien in einer Spalte ablegen

Die Suche in Textfeldern ist oft problematisch

 

Wenn Daten in der Datenbank gesucht werden, so ist bei den Textfeldern bei vielen Datenbanksystemen auf Groß-/Kleinschreibung zu achten. Da die korrekte Schreibweise nicht immer bekannt ist, führen solche Abfragen oft zu leeren Ergebnissen.

 

Als Abhilfe können Sie eine Suchspalte für solche Daten in der Tabelle einführen, in der alle Zeichen z.B. in Großbuchstaben gewandelt werden und alle Leerzeichen entfernt werden.

 

Hiermit wird das Suchergebnis verbessert und der Anwender entlastet.

 


4.8 Einsatz eines Lösch-Flag anstelle direktem delete

Ein UPDATE auf eine Datenzeile ist sehr viel schneller als ein DELETE auf eine Datenzeile

 

Das Löschen von Daten aus der Datenbank ist eine langsame Aktion. Besonders wenn neben den Daten weitere abhängige Tabellen (Referenzielle Integrität) mit aktualisiert werden müssen. In einer transaktionsorientierten Anwendung kann dies die gesamte Performanz bremsen.

 

Eine Möglichkeit besteht darin, in einer weiteren Spalte die primären Daten als gelöscht zu kennzeichnen. Beim Laden der Daten kann dieses Flag ausgewertet werden. Die abhängigen Tabellen benötigen dieses Kennzeichen i.d.R. nicht, da diese über die Verknüpfung nicht geladen werden.

 

In einer Batchaktion können so gekennzeichnete Daten später gelöscht werden. Dies kann man dann auf einen Zeitpunkt verlegen, wenn keine Transaktionen mehr laufen (z.B. nachts).

 


4.9 Nutzen Sie einen Fortschrittsbalken

Subjektive Performanz ist für die Akzeptanz der Anwendung auch wichtig

 

Wenn Abfragen trotz einiger Maßnahmen immer noch lange dauern, dann präsentieren Sie dem Anwender einen Fortschrittsbalken anstelle einer Sanduhr.

 

Damit sieht der Anwender, dass sich was tut und kann den Fortschritt besser einschätzen. Bei einer reinen Sanduhr werden die Benutzer häufig ungeduldig und denken, die Anwendung sei abgestürzt.

 

Das erhöht zwar nicht die Geschwindigkeit der Anwendung, der Anwender ist aber eher bereit, etwas zu warten.

 


4.10 Pre-Loading

Laden Sie die Daten eines kleinen Objektmodellausschnitts in einem Schritt

 

Beim Entwurf eines Objektmodells für Ihre Anwendung werden Sie häufig zusammen gehörende Daten identifizieren können. Laden Sie diese Daten auf einmal über Verknüpfung bei der Abfrage und anschließendem Trennen der Daten in die einzelnen Objekte.

 

Der Performanzvorteil besteht darin, das die Datenbank nur eine größere Abfrage ausführen muss und nicht mehrere kleine Abfragen. Dies bringt einen deutlichen Vorteil in der Laufzeit.

 


4.11 Post-Loading

Laden Sie große Datenmengen in mehreren Schritten

 

Wenn die Datenmenge, die in auf einmal geladen werden muss, zu groß ist, dann teilen Sie die Daten beim Laden auf. Laden Sie einen Teil der Daten und zeigen Sie diese dem Anwender. Wenn er weitere Daten benötigt, so laden Sie diese nach.

 

Durch ein Objektmodell kann dieser Zugriff transparent für den Entwickler und den Anwender implementiert werden. Durch das Objektmodell hat man auch die Möglichkeit, dieses Verhalten nachträglich zu ändern, ohne das der Anwendungsentwickler davon etwas bemerkt.

 

Als Grenze der Daten, die auf einmal geladen werden können, kann man grob von 1.000 Datenzeilen ausgehen.

 


4.12 Caching von Daten

Daten, die die Anwendung schon geladen hat, müssen nicht nochmals geladen werden

 

Wenn Sie Daten aus der Datenbank gelesen haben, so merken Sie sich diese in Ihrem Objektmodell. Diese Daten müssen nicht nochmals in einer weiteren Abfrage angefordert werden. Besonders beim Pre-Loading ist dies sinnvoll.

 

Die in der Datenklassifizierung als statisch eingeschätzte Daten können z.B. von der Factory zur Verfügung gestellt werden. Die Factory lädt diese Daten ein einziges mal. Jedesmal, wenn diese Daten benötigt werden, kann die Factory diese Daten aus dem internen Cache geliefert werden, ohne eine erneute Datenbankabfrage durchzuführen.

 

Sollten die Daten mal geändert werden, so muss man dies dem Factory Objekt mitteilen.

 

Das Caching sollte man bei Bedarf (z.B. zum Testen) auch ausschalten können.

 



Last update:  11.07.2005