Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Auswirkung des Providers auf die Datenbank Performance

Geschrieben von: Christian Koller
Kategorie: Optimierung

This printed page brought to you by AlphaSierraPapa

Um mittels ADO 2.5 eine Datenbank-Verbindung mit Hilfe des Connection Objektes aufzubauen gibt es unterschiedliche Möglichkeiten. Unabhängig davon, ob sich Datenbank und Applikation am selben Server befinden, kann man verschiedene Datenbank Provider benutzen.

Ein Datenbank Provider stellt die Verbindung zwischen der OLE DB Ebene, die unter ADO liegt, und der Datenbank her. Früher hatten Datenbanken oft nur eine ODBC Schnittstelle zur Anbindung an Applikationen zur Verfügung. Daher ist es nicht verwunderlich, daß es lange Zeit unter ADO üblich war, mittels OLE DB Provider für ODBC und dem ODBC Treiber für die jeweilige Datenbank eine Verbindung zwischen Applikation und Datenbank herzustellen. Der ConnectionString für eine ODBC-Verbindung in ADO sieht wie folgt aus:

"Provider=MSDASQL;DSN=DSN-Name;UID=User Name;PWD=Paßwort;"

Seitdem Microsoft ADO zur Standardschnittstelle für den Datenaustausch zwischen verschiedensten Applikationen und Datenquellen aller Art erklärt hat, sind inzwischen spezielle OLE DB Provider für viele Datenbanken erhältlich. Um einen OLE-DB Provider für die Datenbankanbindung zu benutzen wird ein ConnectionString verwendet, der auf den jeweiligen OLE DB Provider zugeschnitten ist:

SQL Server 7.0:
"Provider=SQLOLEDB;Data Source=Server Name;Initial Catalog=" & _ "Datenbank Name;User ID=User Name;Password=Paßwort;"
Access 2000:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Datenbank Pfad;" & _ "User ID=User Name;Password=Paßwort;"

Wenn man nun eine Datenbankverbindung über die ODBC-Schnittstelle errichtet, so müssen alle Daten über 3 Ebenen transportiert werden:

ADO <--> OLE DB Provider für ODBC <--> ODBC Treiber

Hingegen sind in eine Datenbankverbindung direkt über den OLE DB Provider (für die jeweilige Datenbank) nur zwei Ebenen involviert:

ADO <--> OLE DB Provider für die Datenbank

Zusätzlich werden OLE DB Provider bereits optimiert für die jeweilige Datenbank geschrieben, im Gegensatz zu ODBC Treibern, die eine standardisierte ODBC Schnittstelle haben müssen. Daher ist der Einsatz eines OLE DB Providers bei einem Datenbankzugriff prinzipiell schneller als der Einsatz des OLE DB Providers für ODBC (zusammen mit dem jeweiligen ODBC Treiber).

Wie hoch ist aber nun der Geschwindigkeitsgewinn, wenn man statt des OLE DB Providers für ODBC gleich den OLE DB Provider für die Datenbank benutzt?

Um dies zu testen habe ich die gratis erhältliche Profiling Komponente von Alpha Sierra Papa benutzt und in dem folgenden Skript eingesetzt:

<% 
Dim xObj, intI, profileElapsed
Dim connOLEDB, connODBC, rs, strSQL
Dim strConnectionString_OLEDB, strConnectionString_ODBC

strConnectionString_OLEDB = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
   "Data Source=E:\Program Files\Microsoft Office\Office\Samples\" & _
   "Northwind.mdb;User ID=admin;Password=;"
strConnectionString_ODBC = "Provider=MSDASQL;DSN=NW;UID=;PWD=;"
strSQL = "Select LastName, FirstName, BirthDate FROM Employees"

Set xObj = Server.CreateObject("Softwing.Profiler")

Set connODBC = CreateObject("ADODB.Connection")
Set connOLEDB = CreateObject("ADODB.Connection")

Response.Write "Access über ODBC: Recordset auslesen - Start<br>"
xObj.ProfileStart(strSQL)
connODBC.open strConnectionString_ODBC
Set rs = connODBC.Execute()
for intI = 1 to 100
	Set fldLastName = rs("LastName")
	Set fldFirstName = rs("FirstName")
	Set fldGebDat = rs("BirthDate")
	rs.MoveFirst
	While Not rs.EOF
	   strName = fldLastName
	   strAdresse = fldFirstName
	   strGebDat = fldGebDat
	   '...
	   rs.MoveNext
	Wend
Next
rs.close
connODBC.close
profileElapsed = xObj.ProfileStop()
Response.Write "Ergebnis: " & FormatNumber(profileElapsed/10000,3) & _
	" Sekunden<BR><br><br>"

Response.Write "Access über OLEDB: Recordset auslesen - Start<br>"
xObj.ProfileStart()
connOLEDB.open strConnectionString_OLEDB
Set rs = connOLEDB.Execute(strSQL)
for intI = 1 to 100
	Set fldLastName = rs("LastName")
	Set fldFirstName = rs("FirstName")
	Set fldGebDat = rs("BirthDate")
	rs.MoveFirst
	While Not rs.EOF
	   strName = fldLastName
	   strAdresse = fldFirstName
	   strGebDat = fldGebDat
	   '...
	   rs.MoveNext
	Wend
Next
rs.close
connOLEDB.close
profileElapsed = xObj.ProfileStop()
Response.Write "Ergebnis: " & FormatNumber(profileElapsed/10000,3) & _
	" Sekunden<BR><br><br>"

Response.Write "Access über ODBC: Connection öffnen und " & _
	Recordset auslesen - Start<br>"
xObj.ProfileStart()
for intI = 1 to 100
	connODBC.open strConnectionString_ODBC
	Set rs = connODBC.Execute(strSQL)
	Set fldLastName = rs("LastName")
	Set fldFirstName = rs("FirstName")
	Set fldGebDat = rs("BirthDate")
	rs.MoveFirst
	While Not rs.EOF
	   strName = fldLastName
	   strAdresse = fldFirstName
	   strGebDat = fldGebDat
	   '...
	   rs.MoveNext
	Wend
	rs.close
	connODBC.close
Next
profileElapsed = xObj.ProfileStop()
Response.Write "Ergebnis: " & FormatNumber(profileElapsed/10000,3) & _
	" Sekunden<BR><br><br>"

Response.Write "Access über OLE DB: Connection öffnen und " & _
	"Recordset auslesen - Start<br>"
xObj.ProfileStart()
for intI = 1 to 100
	connOLEDB.open strConnectionString_OLEDB
	Set rs = connOLEDB.Execute(strSQL)
	
	Set fldLastName = rs("LastName")
	Set fldFirstName = rs("FirstName")
	Set fldGebDat = rs("BirthDate")
	rs.MoveFirst
	While Not rs.EOF
	   strName = fldLastName
	   strAdresse = fldFirstName
	   strGebDat = fldGebDat
	   '...
	   rs.MoveNext
	Wend
	rs.close
	connOLEDB.close
Next
profileElapsed = xObj.ProfileStop()
Response.Write "Ergebnis: " & FormatNumber(profileElapsed/10000,3) & _
	" Sekunden<BR><br><br>"

Set xObj = Nothing
%>
Fertig...

Anzumerken ist, daß ich vorher die ODBC DSN names NW eingerichtet habe, die genauso auf die Access Datenbank names Northwind verbindet. Ein Durchlauf des Skripts auf meinem Server (Athlon 750 Mhz, Win NT Server) erbrachte folgendes Ergebnis:

Access über ODBC: Recordset auslesen - Start
Ergebnis: 0.533 Sekunden

Access über OLEDB: Recordset auslesen - Start
Ergebnis: 0.109 Sekunden

Access über ODBC: Connection öffnen und Recordset auslesen - Start
Ergebnis: 4.036 Sekunden

Access über OLE DB: Connection öffnen und Recordset auslesen - Start
Ergebnis: 4.014 Sekunden

Das bedeutet, daß der Zugriff auf Daten eines Recordsets unter OLE DB bis zu 5 mal so schnell ist wie unter ODBC.

Realistischer Performance-Gewinn in einer typischen ASP Anwendung bei Verwendung einer Access 2000 oder SQL Server 7.0 Datenbank liegt erfahrungsgemäß zwischen 2 und 10 Prozent, in Einzelfällen aber auch weit darüber. Deshalb lohnt es sich oft, eine Datenbank-Anwendung gleich unter Verwendung eines OLE DB Provider zu programmieren.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20000419.zip

Verwandte Artikel

Ein einfacher Eventkalender für Projektteams
http:/www.aspheute.com/artikel/20020319.htm
Webserver-Tuning mit XTune
http:/www.aspheute.com/artikel/20000814.htm

Links zu anderen Sites

Profiling Komponente
http://www.alphasierrapapa.com/IisDev/Components/Profiler/

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.