什么才是提高ASP性能的最佳选择-续二-
浏览次数:【11】 发布日期:2009-8-13 12:09:22 文章分类:Asp编程
当使用一个记录集时,是否应该建立一个单独的Connection对象?
要想正确回答这个问题,需要在两个不同情境下检验测试结果:第壹是每页执行一个数据库处理的情景,第贰是每页执行多个数据库处理的情景。
在前面的案例中,我们已经建立了一个单独的Connection对象,并将它传递到记录集的ActiveConnection 属性。可是也有可能存在仅仅把连接字符串传递到这个属性中,从而可以防止一个额外的步骤,即在脚本( ADO__03.asp )中例示和配置一个单独的组件:
objRS.ActiveConnection = Application("Conn")
尽管我们仍然在记录集中建立了一个连接,但它是在非常优化的情景下建立的,所以刚一开始我们就看到启动时间比以前的测试减少了23%,同预料中一样,同每个记录的显示时间几乎没有啥不同。
因此,我们的第贰个规则是:
* 当使用一个单个记录集时,将连接字符串传递到ActiveConnection属性中。
下面要确定当在一个页面上建立多个记录集时,这个逻辑是否仍然成立。为测试这个情况,我引入了FOR 循环,将前面的案例重复10次。在这个测试中,我们还将研究3种选择:
第壹,我们在每个循环中建立并销毁Connection 对象( ADO__04.asp ):
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
第贰,在循环外建立一个单独的Connection 对象,并与每个记录集共享它( ADO__05.asp ):
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
第叁,在每个循环中将连接字符串传递到ActiveConnection 属性( ADO__06.asp ):
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
你可能已经猜到了,在每个循环中建立并销毁Connection 对象是一个低效率的要领。可是令人受惊的是,仅仅在每个循环中传递连接字符串比共享单一连接对象的效率只低一点点。
尽管如此,我们的第3条规则是:
* 在一个页面上使用多个记录集时,建立一个Connection 对象,在ActiveConnection 属性中重复使用它。
指针和锁的类型中,哪些是最有效的?
到目前为止,我们所有测试都只用了只向前(Forward Only )的指针在记录集中循环。可是,ADO还为记录集提供了3种类型的指针:Static, Dynamic 和 Keyset。每一种都提供了额外的功能,好比向前和向后移动和当别人建立数据时可以看到更改情况的功能。不过,讨论这些指针类型的内涵不是本文讨论的范畴。我把这些留给你自己。下面是各种类型的比较分析。
与它们的同类Forward Only 相比,这些额外的指针都明显地造成了更大的负载( ADO__03.asp )。另外这些指针在循环期间也更慢。我想与你一起分享的一条忠告是要避免这种想法:“我不时地需要一下Dynamic 指针,所以干脆总是用它算了。”
从本质说,同样的问题也适用于锁的类型。前面的测试中只使用了Read Only(只读)类型的锁。可是,还有三种类型的锁:Lock Pessimistic、 Lock Optimistic和Lock Batch Optimistic。同指针的决策一样,这些锁也为处理记录集中的数据提供了额外的功能和控制。同样,我将学习每种锁设置的适当用途的内容留给你自己。
所以引导我们考虑规则4的理论很简单:使用最适合你的任务的最容易的指针和锁的类型。
获取一个记录集最好的形式是啥?
到目前为止,我们只是通过Recordset 对象来恢复记录集。可是ADO还提供了一点获取记录集的间接方法。下一个测试就将ADO__03.asp 中的值与直接从一个Connection对象中建立一个记录集对象( CONN_01.asp )来比较。
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open Application("Conn")
Set objRS = objConn.Execute(Application("SQL"))
我们看到,负载有一个轻微的增加,显示每条记录的时间没有变化。
然后,我们瞧瞧从一个Command 对象中直接建立一个Recordset 对象( CMD__01.asp ):
Set objCmd = Server.CreateObject("ADODB.Command")
objCmd.ActiveConnection = Application("Conn")
objCmd.CommandText = Application("SQL")
Set objRS = objCmd.Execute
我们再次看到负载有一个轻微的增加,每个记录的显示时间有一个名义上的区别。虽然最后这两种方法对性能的影响很小,却有一个大难题需要考虑。
通过Recordset 类建立一个记录集对于控制如何处理记录集提供了最大的灵活性。虽然其它方法也木有提出一个压倒性的性能问题,可是你会被默认状态下返回何种指针类型和锁类型而困惑,这些对于你的特定需求来说不一定是最优的。
因此,除非因为某种特殊原因你需要其它方法的话,请遵循第5条规则:通过ADODB.Recordset 类例示记录集以获得最好的性能和最大的灵活性。
是否应该断开记录集?
ADO为断开一个记录集提供了一种选择,记录集要在一个向前查询中恢复所有数据、关闭连接、使用一个本地(或客户)指针在数据集中移动。这还提供了一个早期释放连接的机会。这种情景对于处理远程数据