几乎所有关于ADO数据库访问性能分析的文章,都认为二进制组件的性能总是超过解释执行的ASP代码。事实上,这是错误的。从本文的测试结果可以看出,有些时候ASP代码的性能远远超过了组件。

一、引言

  “地球是平坦的...”;
  “太阳绕着地球转...”;
  “总是通过组件访问数据库...”,


  上面三个命题有两个共同的特点:首先,它们都曾经被认为是正确的;其次,这三个命题实际上都是错误的。

  我们都已经读到过无数的文章建议在Internet应用中用组件封装业务逻辑和进行数据库访问,但有关这种技术的实际性能数据却很少看到。随着Windows 2000的发行,IIS平台特别是ASP的性能表现也有了显著的提高。由于先行绑定(Early-binding)内部对象、模板缓冲等诸多改进,在通过ADO访问数据库、格式化并输出记录集等各个方面,ASP都有一流的性能表现。

  从本文测试结果可以看出,ASP在ADO数据库访问、记录集格式化方面胜过组件,而且在某些情形下两者的差异达到了难以置信的程度。对于大多数Internet应用来说,性能总是首要因素,所以在根据传闻或书本知识确定最优方案之前,使用测试工具对方案进行完整的测试是很重要的。

  在进行测试之前,本文的所有三组代码(ASP,VB和C++)都经过了优化。为了确保参与测试的代码其编码方法和测试结果都是各自领域中最优的,它们都经过了多次测试。某些优化工作尚未进行,这是为了让代码更真实地反映出实际应用环境中可能出现的典型情况。

二、测试环境

  本次测试只在Windows 2000平台上进行,在Windows NT平台上测试结果可能会有很大的不同,所以测试所得到的结果不适用于Windows NT平台。下面是本次测试所用系统的示意图及其说明:



  由于测试客户机和Web服务器、数据库服务器所处的物理位置不同,客户机通过三个Cisco 2924交换机连接到Web服务器。所有这些机器都在同一大楼内,但服务器位于数据中心,而测试客户机位于另一个房间,客户机通过一个400Mb Fast EtherChannel连接到数据中心的交换机。

  在这个配置下,测试案例的网络延迟所引起的开销是非常小的。在日常运行中交换机之间的流量总是小于其能力的5%。

三、测试代码

  由于这是一个从ASP、VB组件、C++组件通过ADO进行数据库访问的测试,因此测试代码的功能限于从结果记录集创建一个表格。所有测试程序都可以从本文后面下载。这些程序的执行流程都类似,具体如下:


  使用ODBC DSN创建/打开一个数据库连接
  创建一个Command对象(设置其类型为adCmdStoreProc)
  指定返回记录数量的参数
  执行命令,返回记录集
  关闭记录集和连接,释放这些对象占用的内存。
 可以证实上述方法具有最快的数据库访问速度,这是因为:


  存储过程访问速度要比动态SQL快,即使启用了SQLServer 7.0的SQL计划缓存功能也一样。
  使用Command对象并显式地指定参数要比传入一个查询字符串快得多,这是因为此时OLEDB提供者无需分析查询类型以及所有传递给存储过程的参数的类型。
  ODBC连接池避免了为每一个打开命令创建物理连接。每次关闭连接将把已打开的连接释放回连接池。
结构,这是为了能够让测试程序更加精确地模拟出实际的记录集处理过程。   返回给客户端的HTML代码是从一个两列的记录集创建的<table>结构。所有测试程序都用while循环遍历记录集,而不是用速度更快的GetString方法直接从记录集数据得到<table>结构,这是为了能够让测试程序更加精确地模拟出实际的记录集处理过程。

  测试所用的存储过程从表中提取记录,返回记录的数量以参数形式传递给存储过程。

  测试以多种不同的记录数量和线程数量(并发请求数量)运行。记录数量的范围从0行到100行,但没有测试超过100行的返回记录数量,这是因为考虑到大多数设计良好的Web应用不会出现如此大规模的记录集数据提取和格式化操作。

  线程数量的变化范围从25到2000。在所有测试中,IIS/COM+服务器的处理器利用率大于99%,但在线程数量较少时(25,50),ASP队列长度非常小(或为0)。虽然这些测试也在线程数量设置为1、5、10时运行过,但除了处理器利用率之外,这些线程数量的测试没有表现出任何本质上的不同。

  测试所用的工具是Microsoft的Web Application Stress Tool,测试脚本的基本设置如下:


  所有测试脚本均在网络利用率最低的时候运行。此外,测试期间IIS/COM+服务器和SQL Server上都没有进行其他操作。

  IIS的“应用程序保护”设置成“低”,这使得应用运行具有最好的性能,特别是对COM+库应用的测试来说尤其如此。这个设置同时也允许了所有任务在inetinfo进程内运行。