首页 > 数据库 > Access > 正文

[翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)

2024-09-07 19:05:15
字体:
来源:转载
供稿:网友
[翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data access Techniques) Posted on 2015-01-26 10:50 lsr_flying 阅读(...) 评论(...) 编辑 收藏Performance Comparison: Data Access Techniques

PRiya DhawanMicrosoft Developer Network

January 2002

原文链接:https://msdn.microsoft.com/en-us/library/ms978388.aspx

概要:在典型的应用环境中,比较不同数据访问技术的表现性能。适用于Microsoft .NET Framework Beta2 和 Microsoft SQL Server 2000.(23页打印页)

简介

  数据访问方式的架构选择会对程序的性能、扩展性、可维护性和易用性带来影响。这篇文章的重点在于论述这些选择产生的不同性能表现。数据访问技术包括:Microsoft ADO.NET Command,DataReader,DataSet和xmlReader,这里使用Microsoft SQL ServerTM 2000数据库比较这些不同技术在一些典型的应用环境下的区别。在这些比较当中,会在一定的用户负载范围内对Customer,Order和OrderDetail 数据执行一系列的命令操作。

  展示这些不同数据访问技术的代码示例同样可以使用在讨论ADO.NET的数据访问技术的相关文章当中。这些例子包括了使用ADO.NET访问单个值,单行,多行和层次数据。

测试场景

  任何数据操作的性能表现取决于以下因素:

  数据访问中的对象构造和对象填充会带来很大的系统开销。比如,使用ADO.NET的DataSet进行实例和填充操作就比使用DataReader或XMLReader进行同样操作要占用更多的系统开销。

  数据访问技术对数据库造成的负载情况是不一样的。比如,应用程序读取数据时,DataSet和DataReader使用的连接方式是不一样的。使用存储过程的数据访问技术就比使用动态SQL表达式的方式要少一些数据库的工作负荷。关系型数据与XML之间的转化对服务器资源的使用也与此类似。

  对数据库的数据往返访问的数量也是一个因素,特别是在锁和事务跨越多个数据来回。

  通过网络传输的数据量也是一个关键因素,呈现为xml格式的数据比其它格式的数据要大很多。

  我们使用一些在业务应用当中常用的操作,比如获取一个客户列,查询一个客户的相关订单或者插入一个订单,来比较ADO.NET的不同的数据访问技术。为了使测试更加可靠,数据库加载了超过100,000行的客户账号,一百万行订单(每个客户10个订单)和超过五百万行的订单细节(每个订单有5个细节)。这些数据存在一个SQL Server 2000数据库当中,通过SQL Server .NET data provider连接到SQL Server中。在这里比较的一些方法使用了SQL Server 2000的XML特性。

GetOrderStatus

  GetOrderStatus方法接受一个OrderId,然后返回一个表示这个订单状态的整型。

GetCustomer

  GetCustomer方法接受一个CustomerId参数,然后返回关于该客户信息的一行记录。

GetCustomers

  GetCustomers方法接受一个CustomerId和一个指明你要读取的行数的参数。在所有CustomerID大于传给网页服务方法的CustomerID的行中,将读取最上面的n行数据,并返回。

  我们在一大堆具有不同页数的客户记录中执行带分页的测试。这些客户记录的页数分别为:100,500和1000。 

GetOrders

  GetOrders方法从数据库获取一系列层次订单和它们对应的细节。这个方法接受一个OrderId和一个指明要读取多少订单数的参数。在所有OrderId大于传入的OrderId的记录当中,最上面的n行记录将被读取到。

  我们在一大堆具有不同页数的客户记录中执行带分页的测试。这些客户记录的页数分别为:10个订单(50个细节),50个订单(250个细节)和100个订单(500个细节)。

InsertCustomer

  InsertCustomer方法接受一个customer数据,并向数据库中插入一个customer行,然后将CustomerId作为一个整型返回。  

InsertCustomers

  InsertCustomers方法接受一系列customer类集合,然后向数据库中插入多行对应的customer记录。

InsertOrder

  InsertOrder方法接受的数据,包含了一个带多个detail数据的order记录,并把对应的Order和OrderDetails信息插入数据库当中。测试方法通过插入一个order表头和不同的details来进行。

测试工具

  基于我们的测试目的,我们使用application Center Test(ACT),它适合用于对Web服务器进行压力测试,并分析Web程序的性能和扩展性问题。Web程序就包括ASP页面和它们使用的组件。要了解更多关于创建和运行测试的方法,请参考ACT documentation。使用ACT来测试Web服务器中的不同数据访问技术是很适合的,因为它提供了很多有用的功能来完成测试。首先,它可以通过打开多个对服务器的连接和快速发送HTTP请求来模拟一大组客户并发操作。其次,它也允许我们建立真实的测试环境,在其中我们可以使用有一系列随机参数调用同样的一个方法。这是一个很重要的功能,因为用户不应该反复地利用同样的参数调用同样的方法。另一个更重要的功能就是,Application Center Test会记录测试结果,这些测试结果可以提供关于Web程序性能表现的最重要的信息。

  虽然直接测试数据访问技术,而不是像我们这样通过Web服务器来测试,会让我们得到更好的吞吐量和响应时间,但是在一个无状态的环境下更接近真实的程序应用环境。并且,因为我们基本上是比较这些数据访问技术的相对性能,在无状态环境(也就是在Web服务器背后)中,测试的系统开销在所有情况下都是一样的。

  我们之前讨论的所有数据访问技术都通过.NET Framework程序集进行实施。使用ACT对程序集产生客户负载,我们实现wrapper.aspx页面,所有的客户请求全部都送到这个界面,然后调用程序集。这些程序集中的方法实施了使用ADO.NET技术的数据操作。他们是一些简单的子过程,并不会向.aspx 页面返回数据。当从数据库获得数据行后,这些方法在记录行中进行迭代,然后把列值赋给本地变量。通过在读取从ADO.NET对象中得到的数据时添加延迟,我们模拟使用这些数据进行一些处理操作时的开销。

  测试脚本使用Microsoft VBScript进行编写。根据在test script中执行的具体方法,我们随机化对不同的Customer或Order的请求。比如:

  Dim URL  Dim UB, LB  ' Set the upperbound for Orders list  UB = 1000000  ' Set the lowerbound for Orders list  LB = 1  ' Set the URL  URL  = "http://myServer/DataAccessPerf/DataReader.aspx"  ' Use the Randomize funtion to initialize the Rnd function  Randomize  Test.SendRequest(URL & "?OrderId=" & int((UB – LB + 1)*Rnd + LB))机器配置

  下面的表格对进行测试的测试台配置进行了一个概要总结:  

  表1.客户机配置

# of ClientsMachine/CPU# of CPUsMemoryDiskSoftware
1Dell Precision WorkStation530 MT1694 MHz1512 MB16.9 GB
  • Microsoft Windows® XP
  • Application Center Test

  表2. Web服务器配置

# of ServersMachine/CPU# of CPUsMemoryDiskSoftware
1Compaq Proliant 400 MHz4640 MB50 GB
  • Windows 2000 Advanced Server SP 2
  • .NET Framework Beta 2

  表3. 数据库服务器配置

# of ServersMachine/CPU# of CPUsMemoryDiskSoftware
1American Megatrends Atlantis800 MHz21 GB28 GB
  • Windows 2000 Advance Server SP 2
  • SQL Server Enterprise Edition SP 2Throughput and latency are the key performance indicators. For a given amount of data being returned, throughput is the number of client requests processed within a certain unit of time, typically within a second. Because peak throughput may occur at a response time that is unacceptable from a usability standpoint, we tracked latency, measured as response time using the report generated by Application Center Test for each of the test run, and capped the testing of a given method once the response time exceeded 1 second.

性能测试结果

GetOrderStatus

  这里我们比较使用不同的数据访问技术从数据库获取单个值的表现。

ms978388.bdadotnetarch031_01(en-us,MSDN.10).gif

图1. GetOrderStatus: 吞吐量和延迟

注解

  • 所有的访问都使用存储过程。
  • 在ExecuteScalar方式中,单个值使用command对象的ExecuteScalar方法返回。
  • 在Output参数方式中,单个值作为command对象的一个output参数返回。
  • 在DataReader方式中,DataReader用来获取单个值。
  • 在XmlReader方式中,指明了一个带有FOR XML子句的SQL查询来获得单个值,这个值在XmlReader中以XML的形式保存。

  如图1所示,ExecuteScalar,Output Parameter和DataReader方法获取单个值得性能表现在所有用户负载范围内都很接近。

  但ExecuteScalar方法比其它方法需要更少的代码,因此,从代码维护性的角度来说,是最好的选择。

  XMLReader方法与其它方法相比,会产生更低的尖峰吞吐量,并且包含了FOR XML查询的存储过程会比其它方法使用的存储过程花费更多的时间。

GetCustomer

  这里我们比较从数据库获取单行记录时不同数据访问技术的表现差异。

ms978388.bdadotnetarch031_02(en-us,MSDN.10).gif

图2. GetCustomer: 吞吐量和延时

注解:

  • 所有方法采用存储过程。
  • 在Output参数方法中,单个行记录通过command object的output参数集来返回。
  • 在DataReader方法中,DataReader被用来获取单行记录。
  • XmlReader方法使用一个带FOR XML子句的SQL查询来从数据库中获取一个行记录,这条行记录存储以XML文件的形式存储在XmlReader中。
  • DataSet方法把单行记录填充到DataSet中。

  如图2所示,Output参数和DataReader的方法在不同用户负载范围内表现一致,并且产生比较好的网络吞吐量,均比另外两种方法好。XmlReader方法在吞吐量和响应时间方面表现稍微比DataSet好一些。

  在XmlReader方法中,使用FOR XML的SQL查询比其它方法要花更长的执行时间。

  在这中情况下,DataSet对象的创建引起的系统开销是导致了比较低的吞吐量的主要原因。

GetCustomers

在这个部分,我们比较读取多行记录时(各数据访问技术的)性能表现。我们分别进行返回结果集有100行,500行,1000行记录的测试,以观察数据返回量对性能的影响。

ms978388.bdadotnetarch031_03(en-us,MSDN.10).gif

图 3. GetCustomers (Customers=100): 吞吐量和延时

注解:

  • 所有方法采用存储过程。
  • 在DataReader方法中,DataReader被用来获取多行记录。
  • XmlReader方法使用一个带FOR XML子句的SQL查询来从数据库中获取行记录,这些行记录存储以XML文件的形式存储在XmlReader中。
  • DataSet方法把行记录填充到DataSet中。

  正如你所预料的,从数据库读取更多地行记录会降低每秒的请求数,因为需要处理更多的行记录,并发送这些行记录。

  图3显示了DataReader方法的吞吐量几乎比另外两种方法大两倍。DataSet和XmlReader方法的性能表现几乎一样,不过,在吞吐量方面,XmlReader比DataSet方法稍微好一点点。

ms978388.bdadotnetarch031_04(en-us,MSDN.10).gif

图4. GetCustomers (Customers=500): 吞吐量和延时

<
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表