Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Dipl.-Ing. (FH) Jörn Lenhardt Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 1 von 15 21.4.2003 Inhaltsverzeichnis 1 2 Einführung .......................................................................................................................... 4 Allgemeine Aspekte ........................................................................................................... 5 2.1 Einführung .................................................................................................................. 5 2.2 Datenklassifizierung ................................................................................................... 5 2.3 Datenmengenabschätzung .......................................................................................... 5 2.4 Nutzung von SQL Befehlen ....................................................................................... 6 2.5 Recordsets nur zum Lesen benutzen .......................................................................... 6 2.6 Einsatz von Datenbankscripten .................................................................................. 6 2.7 Aufbau von Testdatenbanken ..................................................................................... 7 2.8 Aufbau eines Objektmodells ...................................................................................... 7 2.9 Abstrakte Primärschlüssel .......................................................................................... 8 2.10 Einsatz von Standard-Datentypen .............................................................................. 8 2.11 Keine Nutzung von Datenbankfeatures ...................................................................... 8 2.12 Umgehen von Outer Join’s ......................................................................................... 9 3 Konsistenz ........................................................................................................................ 10 3.1 Einführung ................................................................................................................ 10 3.2 Nutzung von Foreign Keys ...................................................................................... 10 3.3 Nutzung von Transaktionen ..................................................................................... 10 3.4 Versionierung von Daten ......................................................................................... 10 3.5 Aufbau eines eigenen Nummerngenerators ............................................................. 11 3.6 Eigener Lock von Daten ........................................................................................... 11 4 Performanz ....................................................................................................................... 12 4.1 Einführung ................................................................................................................ 12 4.2 Kritische Betrachtung der Performanz ..................................................................... 12 4.3 Protokollieren Sie die SQL Befehle ......................................................................... 12 4.4 Nutzung von Indizes................................................................................................. 12 4.5 Plausibilität schon auf Clientseite prüfen ................................................................. 13 4.6 Einsatz von IsNew / IsChanged ............................................................................... 13 4.7 Suchkriterien in einer Spalte ablegen ....................................................................... 13 4.8 Einsatz eines Lösch-Flags anstelle direktem Delete ................................................ 14 4.9 Nutzen Sie einen Fortschrittsbalken ......................................................................... 14 4.10 Pre-Loading .............................................................................................................. 14 4.11 Post-Loading ............................................................................................................ 14 4.12 Caching von Daten ................................................................................................... 15 Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 2 von 15 21.4.2003 Tabellenverzeichnis Tabelle 1 - Datenklassifizierung ................................................................................................ 5 Tabelle 2 - Datenmengenabschätzung........................................................................................ 6 Tabelle 3 - Einfache SQL Befehle ............................................................................................. 6 Tabelle 4 - Aufbau verschiedener Datenbanken ........................................................................ 7 Tabelle 5 - Standardmethoden operativer Daten ........................................................................ 8 Tabelle 6 – Basis-Datentypen..................................................................................................... 8 Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 3 von 15 21.4.2003 1 Einführung Bei der Entwicklung von Anwendungen werden häufig Datenbanksysteme (DBS) eingesetzt. Diese werden zur persistenten Speicherung der anfallenden Daten genutzt. Hierbei haben sich SQL Datenbanken als Quasi-Standard durchgesetzt. In diesem Dokument werden einige Aspekte betrachtet, die bei der Entwicklung datenbankgestützter Anwendungen beachtet werden sollten. Hierbei wird auf keine spezielle Datenbank eingegangen. Vielmehr soll dieses Dokument datenbankunabhängig die Planung und Durchführung solcher Entwicklungen beschreiben. Die angesprochenen Themen sind Zusammenfassungen praxisnaher Erfahrungen, die im Rahmen der Entwicklung datenbankgestützter Anwendungen gemacht wurden. Das Dokument gliedert sich in drei Bereiche Allgemeines: Grundlegende Überlegungen zum Umgang mit datenbankgestützten Anwendungen Konsistenz: Sicherstellung der Korrektheit der gespeicherten Daten Performanz: Tuning von Datenbankanwendungen aus Sicht der Applikation Eventuell könnte man den Begriff der Datenbankunabhängigkeit in Allgemeines als Unterpunkte einbringen und dort die Kapitel 2.11 und 3.5 gemeinsam abhandeln (als weitere Unterpunkte) Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 4 von 15 21.4.2003 2 Allgemeine Aspekte 2.1 Einführung In diesem Kapitel werden Themen angesprochen, die zu einer allgemeinen Planung für eine datenbankbasierte Anwendung gehören. Diese sind unabhängig von Konsistenz oder Performanz und gelten für alle Datenbanken. Viele Punkte dieses Kapitels sollten vor der eigentlichen Implementierung festgelegt werden, d.h. schon in der Planungsphase müssen diese vollständig spezifiziert sein. 2.2 Datenklassifizierung Unterscheiden Sie zwischen operative und statischen Daten. Um mit den Daten in der Datenbank umgehen zu können, muss man diese Daten genau kennen. Hierbei hat es sich als vorteilhaft herausgestellt, diese Daten mit dem Kunden zusammen zu klassifizieren. Man klassifiziert zum einen operative Daten, die häufig hinzugefügt, geändert und wieder gelöscht werden. Als zweite Einordnung der Daten werden statische (read only) Daten klassifiziert. Diese Daten werden meist nur einmalig angelegt und selten bis gar nicht geändert oder gelöscht. Hierzu erstellt man einfach eine Tabelle mit allen Datentabellen der Datenbank als Zeilen. Als Spalten schreibt man „operativ“ und „statisch“. So kann man anschließend die entsprechenden Felder ankreuzen. Tabellenname Tabelle 1 Tabelle 2 Tabelle 3 Tabelle 4 operativ x statisch x x x Tabelle 1 - Datenklassifizierung 2.3 Datenmengenabschätzung Versuchen Sie, den Datentransfer einzuschätzen. Neben der Klassifizierung der Daten ist es auch wichtig zu wissen, wie viele Daten überhaupt im Betrieb der Anwendung anfallen. Mit einer zweiten Tabelle (oder in die erste integriert) kann man diese Abschätzung mit dem Kunden gemeinsam durchführen. Man trägt wieder die Datentabellen in die Zeilen dieser Tabelle ein. Als Spalten kann man den täglichen, wöchentlichen, monatlichen und jährlichen Datentransfer pro Tabelle benutzen. Hierbei sind nur grobe Schätzwerte interessant. An diesen kann man aber schon die Tendenzen bezüglich der Datenmengen erkennen. Tabellenname täglich wöchentlich (x5) monatlich (x4) jährlich (x12) Tabelle 1 5 Tabelle 2 20 100 400 4.800 Tabelle 3 70 840 Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Seite 5 von 15 Jörn Lenhardt 21.4.2003 Tabelle 4 Tabelle 5 Tabelle 6 800-1.000 - 4.000-5.000 350 5 16.000-20.000 1.400 60 192.000-240.000 16.800 Tabelle 2 - Datenmengenabschätzung 2.4 Nutzung von SQL Befehlen Benutzen Sie einfaches SQL. Zum Lesen und Schreiben der Daten sollte man möglichst immer SQL Befehle benutzen. Das heißt, zum Lesen benutzt man den SQL Befehl SELECT, zum Schreiben die SQL Befehle INSERT und UPDATE und zum Löschen den SQL Befehl DELETE. Viele Datenbankschnittstellen bieten komfortable Recordsets (z.B. ADO, ADO,NET, DAO) an, mit denen alle Aktionen durchgeführt werden können. Diese Vorgehensweise hat aber den Nachteil, dass man bei diesen Schnittstellen keinen Einblick in die Realisierung der Implementierung und damit in den eigentlichen Ablauf der Befehle hat. Oft arbeiten diese Schnittstellen nicht immer so, wie man es erwartet hätte. Somit ergeben sich häufig Problematiken, die man vergleichsweise bei einer eigenen Implementierung nicht hat oder selbst beheben kann. Befehl SELECT INSERT UPDATE DELETE Bedeutung Lesen von Daten Hinzufügen von Daten Ändern von Daten Löschen von Daten Tabelle 3 - Einfache SQL Befehle 2.5 Recordsets nur zum Lesen benutzen Vertrauen Sie auf die eigene Implementierung. Die Benutzung dieser Recordsets kann man bei eigener Implementierung auf Nur-LeseRecordsets mit Nur-Vorwärts-Richtung auf serverseite beschränken. Diese Recordsets erfüllen dann alles, was man zum Lesen der Daten benötigt und sind mit diesen Einstellungen i.d.R. sehr schnell. Damit sind diese Recordsets auch datenbankübergreifend einsetzbar, was eine Portierung der Anwendung auf eine andere Datenbank wesentlich vereinfacht. 2.6 Einsatz von Datenbankscripten Erzeugen Sie Datenbanken nur mit Scripten, nicht mit GUI Werkzeugen. Wenn Datenbanken für Anwendungen aufgebaut werden müssen, dann erzeugen Sie aus dem Modell immer ein Datenbankscript. Benutzen Sie niemals die grafischen Tools zur schnellen Erzeugung der Datenbanken. Die mittels grafischer Tools erstellten Datenbanken haben den Nachteil, dass man nicht immer alle Schritte zur Erzeugung der originalen Datenbank beim Aufbau einer zweiten Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 6 von 15 21.4.2003 Datenbank nachvollziehen kann (weil man einiges vergessen hat!). Somit können ungewollte Überraschungen bei der Inbetriebnahme der zweiten Datenbank vermieden werden. Normalerweise hat man schon während der Entwicklung mehrere Datenbanken laufen, die man konsistent halten muss. Dies erreicht man am Besten mit Scripten. Auch Update’s dieser Schemata sollten immer über ein Script erfolgen (Sie werden es spätestens dann bemerken, wenn Sie mehr als hundert Kunden betreuen sollen). 2.7 Aufbau von Testdatenbanken Planen Sie genügend Testdatenbanken ein, auch beim Kunden. Wenn eine Anwendung entwickelt wird, stellen Sie jedem Entwickler eine eigene Datenbank als Spielwiese zur Verfügung. Jeder Mitarbeiter entwickelt eigene Teile der Anwendung, die er ausgiebig mit seinen eigenen Daten testen kann. Hierbei wird er häufig Daten einfügen und wieder Löschen. Damit er keine Daten eines anderen Entwicklers ändert, ist der Einsatz einer eigenen Datenbank sinnvoll. Zur Präsentation der Anwendung sollten Sie immer eine eigene Datenbank vorhalten. Ihr Chef oder Ihr Kunde werden sich irgendwann über den Stand der Entwicklung informieren wollen. Entwicklerdatenbanken sind hierfür selten geeignet, da hier i.d.R. alles im (Vor-) Beta Stadium ist. Zum Stresstest sollten Sie eine weitere Datenbank mit vielen Daten haben. Erzeugen Sie das normale Schema und fügen Sie in die Tabellen einfach mal Millionen Datensätze ein. Mit dieser Datenbank können Sie jederzeit Performanz- und Stresstests durchführen. Hierbei fallen einige Engpässe direkt auf. Datenbank Entwickler Vorführung Produktiv Test Anzahl n 1 1 1..m Wofür Entwicklerdatenbank, für jeden Entwickler eine Vorführdatenbank im Haus Produktivdatenbank beim Kunden Testdatenbank beim Kunden für Beta Tests, ... Tabelle 4 - Aufbau verschiedener Datenbanken 2.8 Aufbau eines Objektmodells Abstrahieren Sie den Zugriff auf die Datenbank. Entwickeln Sie parallel zum Datenbankmodell ein Objektmodell für die Entwickler. Mit diesem Modell abstrahieren Sie den Datenbankzugriff für die Mehrzahl der Entwickler. Stellen Sie Klassen und Methoden für die Bearbeitung der Daten zur Verfügung, ohne hierbei auf die Datenbank direkt zu verweisen. (Verweis auf Mapping: Hier könnte man eventuell die Papiere von Scott Ambler nennen) Zum Laden der Daten aus der Datenbank entwerfen Sie eine (oder mehrere) Factory Klassen. Zum Speichern der Daten geben Sie dem Objekt z.B. eine Save() Methode. Kein Entwickler fachlicher Logik soll sich um die Details der Datenbankanbindung kümmern müssen. Bieten Sie ihm eine vollständige Schnittstelle, um die Aufgabenbereiche einfach zu trennen. Folgende Methoden können sie den Anwendungsentwicklern pro operativer Klasse zur Verfügung stellen. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 7 von 15 21.4.2003 Methode Save GetAll<Details> Get<Detail>(Kriterium) Get<Detail>Count Add<Detail> Remove<Detail>(Kriterium) RemoveAll<Detail> Bedeutung Speichert das Objekt (und evtl. dazugehörige Objekte) Liefert eine Liste aller Detaildaten Liefert ein Detaildatum anhand eines eindeutigen Kriteriums Liefert die Anzahl der Detaildaten Fügt ein Detaildatum in die Liste ein Entfernt ein Detaildatum anhand des Kriteriums Entfernt alle Detaildaten aus der Liste Tabelle 5 - Standardmethoden operativer Daten 2.9 Abstrakte Primärschlüssel Benutzen Sie abstrakte Primärschlüssel, keine fachlichen Primärschlüssel. Bei der Wahl von Primärschlüssel für eine Tabelle benutzen Sie am besten abstrakte Schlüssel. Hierbei kann man eine ID Spalte mit Ganzzahlen einsetzen. Primärschlüssel aus fachlichen Daten (wie z.B. Name, Vorname) haben sich in durchgeführten Projekten als unpraktisch herausgestellt. Bei Änderung der fachlichen Daten, die Teil des Primärschlüssels sind, müssen auch alle anderen Tabellen, die diese als Fremdschlüssel enthalten, geändert werden. Das ist zum einen ein enormer Verwaltungsaufwand und zum anderen performanzmindernd. 2.10 Einsatz von Standard-Datentypen Seien Sie vorsichtig mit der Wahl der benutzen Datentypen. Verwenden Sie nach Möglichkeit nur Basis-Datentypen Benutzen Sie nicht immer alle Datentypen, die Ihnen eine Datenbank zur Verfügung stellt. Konzentrieren Sie sich auf einige Basis-Datentypen, die Sie verwenden. Häufig finden Sie auf anderen Datenbanken keine Entsprechung solcher proprietärer Typen, so dass eine Portierung der Anwendung auf eine andere Datenbank Probleme bereitet. Sollte man eventuell nur kurz den Begriff der „Datenbankunabhängigkeit“ bringen? Datentyp VARCHAR MEMO INTEGER DOUBLE CURRENCY DATE TIME Bedeutung Ein Test mit einer max. Länge (meist 1-4 K) Ein Text mit (fast) unbegrenzter Länge Ganzzahlen Gleitkommazahlen Währung Datum Uhrzeit Tabelle 6 – Basis-Datentypen 2.11 Keine Nutzung von Datenbankfeatures Beschränken Sie sich auf einfachstes Standard SQL. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 8 von 15 21.4.2003 Bei dem Entwurf der SQL Befehle (insbesondere bei Abfragen) bieten Datenbanken häufig viele Features (erweiterte Skalarfunktionen, ...). Selten sind diese Features auf anderen Datenbanken so verfügbar, so dass eine Portierung viel Mühe kostet. Verzichten Sie auf solchen „Komfort“ und programmieren Sie diese Funktionen selbst. 2.12 Umgehen von Outer Join’s Weiß noch nicht, ob ich dies ansprechen soll. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 9 von 15 21.4.2003 3 Konsistenz 3.1 Einführung Ein wichtiges Thema bei der Planung und Umsetzung datenbankgestützter Anwendungen im Multi-User-Umfeld ist die Konsistenz der Daten. Hierbei muss sichergestellt sein, das bei einer gleichzeitigen Benutzung einer gemeinsamen Datenbasis die Daten durch die Parallelzugriffe nicht inkonsistent werden dürfen. Hierfür gibt es einige Techniken, die im praktischen Betrieb, also in der Implementierung solcher Anwendungen, immer wieder eingesetzt werden. Viele dieser Techniken sind schon im Design zu berücksichtigen. Dadurch sollte man sich frühzeitig bei der Planung einer solchen Anwendung mit die 3.2 Nutzung von Foreign Keys Beschreiben Sie die Beziehungen zwischen den Daten mit Fremdschlüsseln (Foreign Keys). Bei der Erstellung des Datenbankmodells sollten nicht nur die Tabellen mit ihren Spalten beschrieben werden. Auch die Beziehungen der Tabellen untereinander sollten der Datenbank mitgeteilt werden. Dadurch kann die Datenbank Konsistenzprüfungen auf den Daten durchführen und teilt Verletzungen dieser Konsistenz der Anwendung mit. Hierauf können Sie entsprechend reagieren. Ohne die Foreign Keys können Sie von der Anwendung heraus inkonsistente Beziehungen speichern, ohne das Sie es merken. Erst beim erneuten Lesen der Daten werden Sie bemerken, das Daten „fehlen“, ohne zu wissen, wo sich diese Daten befinden. Foreign keys bedeuten für die Datenbank zwar einen erhöhten Verwaltungsaufwand beim Ändern der Daten, diese Laufzeitverluste stehen aber im keinem Verhältnis zur Konsistenz der Daten. 3.3 Nutzung von Transaktionen Transaktionen sichern das konsistente Schreiben der Daten. Vielfach wird beim Schreiben der Daten mehr wie eine Tabelle verändert. Damit bei der Änderung der Tabellen nicht dazwischen ein Fehler auftritt und so nur Teile der Daten geschrieben und der andere Teil verworfen werden, fassen Sie die Änderungen in einer Transaktion zusammen. So wird von der Datenbank sichergestellt, das entweder alle Änderungen oder keine Änderung durchgeführt wird. Heute bieten die meisten Datenbanken Transaktionskonzepte, so das diese Technik als Standard angesehen werden kann. (Vorsicht bei mySQL) 3.4 Versionierung von Daten Nutzen Sie eine Versionierung der Daten bei Multi User Anwendungen. Bei größeren Anwendungen kommt es häufig vor, das gleiche Daten parallel von verschiedenen Benutzern gelesen und geändert werden. Damit kein Anwender Daten Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 10 von 15 21.4.2003 überschreibt, die ein anderer Anwender zuvor geändert hat, geben sie jeder Datenzeile in der Datenbank eine Version (eine eigene Spalte VERSION). Beim Lesen hat jeder Anwender eine Version der Daten (welche die gleiche Version sein kann, wie sie auch ein anderer Anwender hat). Beim Schreiben der Daten beziehen Sie sich dann auf die Version und zählen diese dann um eins hoch. Falls mehrere Benutzer parallel versuchen, die Daten zu schreiben, kann dies nur einer tun, da nur bei ihm die gelesene Version mit der Version beim Schreiben übereinstimmt. Der andere Anwender bekommt eine Fehlermeldung, dass seine Daten aufgrund der Version nicht geschrieben werden können. Als Entwickler der Anwendung müssen Sie dann auf solche Fehler reagieren (z.B. erneutes Laden der geänderten Daten). 3.5 Aufbau eines eigenen Nummerngenerators Entwickeln Sie für die eindeutige Vergabe von Nummern einen eigenen Nummerngenerator. Nicht alle professionellen Datenbanken bieten ein solches Feature, weswegen Sie auch auf einen proprietären Nummerngenerator verzichten sollten. Dieser Nummerngenerator lässt sich für die Vergabe der Primärschlüssel als auch für die Vergabe von Nummern in der fachlichen Implementierung einsetzen. 3.6 Eigener Lock von Daten Sperren Sie Daten, deren Änderung kritisch ist. Um Parallelzugriffe auf Daten auszuschließen, können sie auch die entsprechenden Datensätze in der Datenbank von Hand sperren. Dadurch können Sie die Probleme, die bei der Versionierung angesprochen wurden, umgehen (dies soll aber nicht bedeuten, dass Sie auf die Versionierung verzichten sollen). Hierzu benötigen Sie zwei Spalten in der Tabelle. Die eine Spalte beinhaltet den Lockzeitstempel, die andere den Lockbenutzer. Falls ein Benutzer Daten zum Ändern aus der Datenbank lädt, füllt er die beiden Spalten mit Werten. Falls ein anderer Benutzer diese Daten laden will, sieht er, das ein anderer Benutzer diese Daten für sich gesperrt hat. Wenn der Benutzer die Daten geändert hat, löscht er die beiden Einträge in den Spalten und stellt so den Datensatz für andere Benutzer wieder zur Verfügung. Die Zeitstempelspalte sollte in einem Timer zyklisch von der Anwendung aktualisiert werden. Falls der Client während der Bearbeitung abstürzt (soll ja vorkommen), so wird diese Spalte nicht mehr aktualisiert. So kann anhand des Zeitstempels entschieden werden, ob die Daten weiterhin gesperrt sind oder nicht. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 11 von 15 21.4.2003 4 Performanz 4.1 Einführung 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. Nach praktischen Erkenntnissen sind ca. 90% der Engpässe in der Performanz durch eine gute Planung und Umsetzung der Anwendung zu vermeiden. 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 der 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 Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 12 von 15 21.4.2003 sinnvoll ist oder nicht. Grundlage für diese Beurteilung spielen Datenmengenabschätzung sowie die Selektivität der zu indizierenden Spalte. 4.5 u.a. die 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. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 13 von 15 21.4.2003 4.8 Einsatz eines Lösch-Flags 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. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 14 von 15 21.4.2003 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. Applikationsbasiertes Performanztuning datenbankgestützter Anwendungen Jörn Lenhardt Seite 15 von 15 21.4.2003