Datenbankschnittstellen zeichnen sich in erster Linie durch rigide Verwendungsvorschriften aus. Microsofts ADO.NET ist zwar einfacher und flexibler, führt aber immer wieder zu Performance-Problemen. Bei Beachtung einiger Grundregeln sind diese leicht zu vermeiden. Woran liegt es, dass eine Applikation zu langsam ist? Was kann man dagegen tun? Wäre es nicht praktisch, bereits während der Entstehung einer Applikation eine Meldung wie System.YourCodeIsRunningTooSlowException zu erhalten, die auf Performance-Probleme aufmerksam macht? Leider hat Microsoft ein solches Exception Handling im .NET Framework vergessen. Aus leidvoller Erfahrung wissen Entwickler, dass sich Probleme bei der Arbeitsgeschwindigkeit einer Applikation erst im Alltag zeigen. Gerade wegen der großen Spielräume, die .NET erlaubt, ist es alles andere als ein Kinderspiel, Code zum Zugriff auf Datenbanken zu schreiben, der durch schnelle Antwortzeiten glänzt. Die ADO.NET-Dokumentation enthält für diese Fälle nicht mehr als einige dürftige Grundregeln und Schnittstellendefinitionen. Aus der Analyse einer Vielzahl von .NET-Applikationen, die DataDirect Technologies bei Unternehmen antraf, haben sich fünf typische Fehler herauskristallisiert, die auf jeden Fall vermieden werden sollten.
Als Diensteplattform verfügt Microsoft .NET über eine Vielzahl von Funktionen zum Erstellen modernster Anwendungen. Die Microsoft-.NET-Plattform beruht auf Standard-Data-Connectivity-Komponenten. Microsoft bezeichnet sie als Data Provider. Sie sind als ADO.NET-Schnittstellen implementiert und bieten Applikationen eine Reihe von Diensten in Gestalt von Klassen. ADO.NET unterscheidet sich von anderen generischen Datenbankschnittstellen wie ADO oder ODBC insbesondere durch die bessere Kontrolle darüber, was mit den Daten geschieht. Der Preis dafür ist der Verlust bestimmter Vorteile, die generische Datenbankschnittstellen bieten. So gibt es beispielsweise in ADO.NET standardmäßig keinen Parameter-Marker. Diesen stellt DataDirect Technologies jedoch mit seiner Connectivity-Komponente DataDirect Connect for .NET zusätzlich bereit - Entwickler werden damit unabhängig vom jeweiligen Datenbankmanagement-System wie Oracle, Sybase oder SQL Server.
Tipp 1: Kein CommandBuilder verwenden
Viele Programmierer benutzen das CommandBuilder -Objekt, um Informationen aus einer SQL-Datenbank zu holen - der Grund: Es spart Entwicklungszeit. Die vermeintliche Abkürzung entpuppt sich jedoch sehr schnell als großer Umweg, im schlimmsten Fall sogar als Performance-Bremse. Insbesondere wegen der Restriktionen beim gleichzeitigen Zugriff auf Datenquellen produziert CommandBuilder häufig ineffiziente SQL-Statements. Das lässt sich an folgendem Beispiel beim Update einer aus acht Spalten bestehenden relationalen Tabelle namens EMP verdeutlichen. Der CommandBuilder würde ein Update-Statement wie in Listing 1 genieren.Listing 1Dieses "UPDATE-Monster" wurde vom CommandBuilder generiertUPDATE EMP SET EMPNO = ?, ENAME = ?, JOB = ?, MGR = ?, HIREDATE = ?, SAL = ?, COMM = ?, DEPT = ? WHERE ( (EMPNO = ?) AND (ENAME = ?) AND (JOB = ?) AND ((MGR IS NULL AND ? IS NULL) OR (MGR = ?)) AND (HIREDATE = ?) AND (SAL = ?) AND((COMM IS NULL AND ? IS NULL) OR (COMM = ?)) AND (DEPT = ?) )
UPDATE EMP SET EMPNO = ?, ENAME = ?, JOB = ?, MGR = ?,HIREDATE = ?, SAL = ?, COMM = ?, DEPT = ? WHERE EMPNO = ?
Tipp 2: Nicht ohne Not-Long-Daten abfragen
Als Performance-Bremse schlechthin erweisen sich bei SQL-Abfragen Long -Daten. Derartige Daten vom Typ Character besitzen eine variable Länge von bis zu 65.535 Zeichen und werden zum Beispiel für Bilder verwendet - in aller Regel ist maximal eine Spalte vom Typ Long je Tabelle zulässig. Als Faustregel gilt: Wo Performance zählt, sollten Applikationen nur, wenn es wirklich unbedingt notwendig ist, Datenfelder mit Long -Daten abfragen. Enthält das Select -Statement Tabellenspalten mit Long -Daten, müssen die meisten .NET Data Provider (Datenbanktreiber) alle Tabelleneinträge in der Ergebnismenge zusammenstellen - und das selbst dann, wenn die Applikation die Long -Daten im konkreten Fall gar nicht benötigt. Wo immer möglich, sollten Entwickler deshalb Methoden verwenden, mit denen sich die Zahl der abgefragten Tabellenspalten einschränken lässt. Dies schließt nicht benötigte Long -Datenspalten von vornherein aus. Mehr noch: Anwender wollen in einer Ergebnisliste den Inhalt einer derartigen Datenspalte meist gar nicht sehen. Es werden also unnötig Daten transportiert. Sollten die Inhalte jedoch tatsächlich weiterverarbeitet werden, dann genügt es, nur die Long -Daten in einer Select -Liste zu spezifizieren.Tipp 3: Autocommit in Transaktionen vermeiden
Die Anweisung Commit Transaction speichert alle seit Beginn einer Transaktion (konkret: seit Ausführung der Anweisung Begin Transaction ) unternommenen Operationen. Daher enthält eine Commit -Anweisung immer Zugriffe auf die Festplatte und belastet auch das Netzwerk. Stellt eine Applikation eine Verbindung zu einer Datenbank her, erfolgt dies häufig im Autocommit -Modus. Muss jede Operation bestätigt werden, hat das spürbare Auswirkungen auf die Performance. Zudem muss der Datenbankserver jede Data Page mit geänderten oder neuen Daten auf die Platte schreiben. Auch das beansprucht Zeit, selbst wenn der Zugriff sequenziell erfolgt. Statt im Modus Autocommit sollte eine Transaktion daher erst nach Aufbau einer Verbindung zur Datenbank gestartet werden. Nun verfügen einige Datenbankserver nativ nicht über den Autocommit -Modus. In dem Fall muss der Datenbanktreiber explizit mit Begin Transaction und Commit arbeiten. Das Codefragment in Listing 2 startet eine Transaktion für Oracle.Listing 2OracleConnection MyConn = new OracleConnection("Connection String info");MyConn.Open()// Start a transactionOracleTransaction TransId = MyConn.BeginTransaction();// Enlist a command in the current transactionOracleCommand OracleToDS = new OracleCommand();OracleToDS.Transaction = TransId;...// Continue on and do more useful work in the// transaction
Tipp 4: Vorsichtige Verwendung von Command.Prepare
Um einem SQL-Statement während der Laufzeit variable Werte mitzugeben, kommen so genannte Parameter-Marker zum Einsatz. Die allermeisten ADO.NET Data Provider benutzen als Parameter-Marker in den SQL-Statements die native Syntax des jeweiligen DBMS. Unter Verwendung des Microsofts SQL Server Data Provider könnte ein einfaches SQL-Statement etwa so lauten:Select * from table where column=@parametername
Select * from table where column=:parametername
Select * from table where column=?




