什么才是提高ASP性能的最佳选择(续二)

80酷酷网    80kuku.com

  性能当使用一个记录集时,是否应该创建一个单独的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为断开一个记录集提供了一种选择,记录集要在一个向前查询中恢复所有数据、关闭连接、使用一个本地(或客户)指针在数据集中移动。这还提供了一个早期释放连接的机会。这种情况对于处理远程数据

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: