< SCRIPT LANGUAGE=VBScript RUNAT=Server >
Sub Application_OnStart
Application("Conn") = "Provider=SQLOLEDB; " & _
"Server=MyServer; " & _
"uid=sa; " & _
"pwd=;" & _
"DATABASE=northwind"
Application("SQL") = "SELECTTOP 0OrderID, " & _
"CustomerID, " & _
"EmployeeID, " & _
"OrderDate, " & _
"RequiredDate, " & _
"ShippedDate, " & _
"Freight " & _
"FROM[Orders] "
End Sub
< /SCRIPT >
'alternate sql - 25 records
Application("SQL") = "SELECTTOP 25OrderID, " & _
"CustomerID, " & _
"EmployeeID, " & _
"OrderDate, " & _
"RequiredDate, " & _
"ShippedDate, " & _
"Freight " & _
"FROM[Orders] "
'alternate sql - 250 records
Application("SQL") = "SELECTTOP 250 OrderID, " & _
"CustomerID, " & _
"EmployeeID, " & _
"OrderDate, " & _
"RequiredDate, " & _
"ShippedDate, " & _
"Freight " & _
"FROM[Orders] "
测试服务器配置如下:450 Mhz Pentium,512 MB RAM,NT Server 4.0 SP5,MDAC 2.1(数据访问组件),以及5.0版本的Microsoft脚本引擎。SQL Server运行在另外一台具有类似配置的机器上。和第一部分一样,我们仍旧使用Microsoft Web Application Stress Tool 记录从第一个页面请求到从服务器接收到最后一个字节的时间(TTLB,Time To Last Byte),时间以毫秒为单位。测试脚本调用每个页面1300次以上,运行时间约20小时,以下显示的时间是会话的平均TTLB。请记住,和第一部分一样,我们只关心代码的效率,而不是它的可伸缩性或服务器性能。 < % Option Explicit % >
< !-- #Include file="ADOVBS.INC" -- >
< %
Dim objConn
Dim objRS
Response.Write( _
"< HTML >< HEAD >" & _
"< TITLE >ADO Test< /TITLE >" & _
"< /HEAD >< BODY >" _
)
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open Application("Conn")
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.ActiveConnection = objConn
objRS.CursorType = adOpenForwardOnly
objRS.LockType = adLockReadOnly
objRS.Open Application("SQL")
If objRS.EOF Then
Response.Write("No Records Found")
Else
'write headings
Response.Write( _
"< TABLE BORDER=1 >" & _
"< TR >" & _
"< TH >OrderID< /TH >" & _
"< TH >CustomerID< /TH >" & _
"< TH >EmployeeID< /TH >" & _
"< TH >OrderDate< /TH >" & _
"< TH >RequiredDate< /TH >" & _
"< TH >ShippedDate< /TH >" & _
"< TH >Freight< /TH >" & _
"< /TR >" _
)
'write data
Do While Not objRS.EOF
Response.Write( _
"< TR >" & _
"< TD >" & objRS("OrderID") & "< /TD >" & _
"< TD >" & objRS("CustomerID") & "< /TD >" & _
"< TD >" & objRS("EmployeeID") & "< /TD >" & _
"< TD >" & objRS("OrderDate") & "< /TD >" & _
"< TD >" & objRS("RequiredDate") & "< /TD >" & _
"< TD >" & objRS("ShippedDate") & "< /TD >" & _
"< TD >" & objRS("Freight") & "< /TD >" & _
"< /TR > " _
)
objRS.MoveNext
Loop
Response.Write("< /TABLE >")
End If
objRS.Close
objConn.Close
Set objRS = Nothing
Set objConn = Nothing
Response.Write("< /BODY >< /HTML >")
% >
下面是测试结果:objRS.CursorType = 0?' adOpenForwardOnly
objRS.LockType = 1' adLockReadOnly
< !--METADATA TYPE="typelib"
FILE="C:Program FilesCommon FilesSYSTEMADOmsado15.dll"
NAME="ADODB Type Library" -- >
或者:
< !--METADATA TYPE="typelib"
UUID="00000205-0000-0010-8000-00AA006D2EA4"
NAME="ADODB Type Library" -- >
因此,我们的第一条规则为:objRS.ActiveConnection = Application("Conn")
虽然Recordset对象仍旧要创建一个连接,但此时的创建是在高度优化的条件下进行的。因此,与上一次测试相比,页面开销又下降了23%,而且如预期的一样,单个记录的显示时间没有实质的变化。Dim i
For i = 1 to 10
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open Application("Conn")
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.ActiveConnection = objConn
objRS.CursorType = 0 'adOpenForwardOnly
objRS.LockType = 1 'adLockReadOnly
objRS.Open Application("SQL")
If objRS.EOF Then
Response.Write("No Records Found")
Else
'write headings
...
'write data
...
End If
objRS.Close
Set objRS = Nothing
objConn.Close
Set objConn = Nothing
Next
第二,如ADO__05.asp所示,在循环外面创建Connection对象,所有记录集共享该对象:Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open Application("Conn")
Dim i
For i = 1 to 10
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.ActiveConnection = objConn
objRS.CursorType = 0 'adOpenForwardOnly
objRS.LockType = 1 'adLockReadOnly
objRS.Open Application("SQL")
If objRS.EOF Then
Response.Write("No Records Found")
Else
'write headings
...
'write data
...
End If
objRS.Close
Set objRS = Nothing
Next
objConn.Close
Set objConn = Nothing
第三,如ADO__06.asp所示,在每一个循环内把连接串赋给ActiveConnection属性:Dim i
For i = 1 to 10
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.ActiveConnection = Application("Conn")
objRS.CursorType = 0 'adOpenForwardOnly
objRS.LockType = 1 'adLockReadOnly
objRS.Open Application("SQL")
If objRS.EOF Then
Response.Write("No Records Found")
Else
'write headings
...
'write data
...
End If
objRS.Close
Set objRS = Nothing
Next
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open Application("Conn")
Set objRS = objConn.Execute(Application("SQL"))
可以看到页面开销略有增加,单个记录的显示时间没有变化。 Set objCmd = Server.CreateObject("ADODB.Command")
objCmd.ActiveConnection = Application("Conn")
objCmd.CommandText = Application("SQL")
Set objRS = objCmd.Execute
同样,页面开销也略有增加,而单个记录的显示时间没有本质的变化。后面这两种方法在性能上的差异很小,但我们还有一个重要的问题需要考虑。 Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.CursorLocation = 2' adUseClient
objRS.ActiveConnection = Application("Conn")
objRS.LockType = 1?' adLockReadOnly
objRS.Open Application("SQL")
objRS.ActiveConnection = Nothing
理论上,这种方法由于以下两个原因会对效率有所好处:第一,它避免了在记录之间移动时重复地通过连接请求数据;第二,由于能够方便地释放连接,它减轻了资源需求。然而,从上表看起来使用本地记录集对提高效率显然没有什么帮助。这或许是因为使用本地记录集时,不管程序设置的是什么,游标总是变成静态类型。 'write data
Do While Not objRS.EOF
Response.Write( _
"< TR >" & _
"< TD >" & objRS(0) & "< /TD >" & _
"< TD >" & objRS(1) & "< /TD >" & _
"< TD >" & objRS(2) & "< /TD >" & _
"< TD >" & objRS(3) & "< /TD >" & _
"< TD >" & objRS(4) & "< /TD >" & _
"< TD >" & objRS(5) & "< /TD >" & _
"< TD >" & objRS(6) & "< /TD >" & _
"< /TR > " _
)
objRS.MoveNext
Loop
[1] [2] 下一页
……