构建快速数据交易系统的思考(1)使用DataDirect
<<构建快速数据交易系统的思考>>系列将从软件架构设计的各个层面对提高系统性能方法和策略进行研究。
本文是系列“构建快速数据交易系统”的第一篇文章,将就如何从数据访问机制层面来改善系统性能的方法进行探讨 。
架构决定了应用程序的性能。 软件架构师经常相信,只要提高软件基础设施的性能(比如硬件资源)将足以解决一个应用程序的性能挑战,但不幸的是它已被证明在许多实际情况下都以失败而告终。
系统性能是应用程序一个重要的指标,应当在整个项目生命周期的初始阶段就开始考虑,它将贯穿于整个生命周期和系统的各个组成部分。

Data provider是应用程序和数据源之间的桥梁 ,主要用于从数据源检索数据 。 除了微软的ADO.net外,也有很多商业数据提供商,例如DataDirect 等等。DataDirect是一个高性能商业的数据访问组件,它已被广泛使用于金融,电信等行业。
今天,我们将建立一个简单的演示的控制台应用程序,比较微软的ADO.Net和DataDirect作为data
provider的性能。
应用场景 :
我们有一个交易数据库,其中包含近1百万条纪录存储在order表。
在同时我们有一个存储过程 GetOrderPrice ,用于计算某个order的总价
(1)订单表:

(2)SP:GetOrderPrice
CREATE PROCEDURE [dbo].[GetOrderPrice]
@orderIndex int
AS
BEGIN
SET NOCOUNT ON;
SELECT Qty*UnitPrice from [Order] WHERE Id=@orderIndex;
END
应用环境
| 
 数据库实例  | 
 Microsoft SQL Server 2008 (SP1) - 10.0.2573.0 (X64)   Developer Edition (64-bit) on Windows NT
  6.1 <X64> (Build 7600: )  | 
| 
 数据库服务器(虚拟机)  | 
 Windows 2008 server R2 ( AMD Poteron™ Processor 6128 2.00 GHZ (2
  processors)  | 
| 
 Installed Memory: 6.00 GB  | 
|
| 
 Visual Studio版本  | 
 VS2010 Ultimate  | 
| 
 性能监视器  | 
 StopWatch  | 
| 
 Data Providers  | 
 Microsoft ADO.net VS DataDirect for ADO.net  | 
((1) 利用DataDirect调用SP:
static void CallSPWithDataDirect(int orderIndex)
 {
SQLServerCommand DBCmd;
      using (SQLServerConnection
Conn = new SQLServerConnection(connectionStrDataDirect))
      {
           
Conn.Open();
           
DBCmd = new SQLServerCommand("GetOrderPrice", Conn);
           
DBCmd.CommandType = CommandType.StoredProcedure;
           
DBCmd.Parameters.Add("@orderIndex",
SQLServerDbType.Int, 10).Value = orderIndex;
            decimal result = (decimal)DBCmd.ExecuteScalar();
      }
 }
((2)  利用ADO.net调用SP:
static void
CallSPWithADOnet(int orderIndex)
 {
     SqlCommand DBCmd;
     using (SqlConnection
Conn = new SqlConnection(connectionStrADO))
     {
         
Conn.Open();
          DBCmd
= new SqlCommand("GetOrderPrice", Conn);
         
DBCmd.CommandType = CommandType.StoredProcedure;
         
DBCmd.Parameters.Add("@orderIndex",
SqlDbType.Int, 10).Value = orderIndex;
          decimal result = (decimal)DBCmd.ExecuteScalar();
}
}
测试方案:
在一个循环内多次调用存储过程 GetOrderPrice随机读取某个order的总价,利用StopWatch比较不同的数据提供者的总体响应时间。
测试结果 :
| 
 SP执行次数  | 
 DataDirect  | 
 ADO.net  | 
||
| 
 1000  | 
 1.149  | 
 4.7298  | 
||
| 
 2000  | 
 1.778  | 
 11.098  | 
||
| 
 3000  | 
 2.409  | 
 13.72  | 
||
| 
 4000  | 
 2.836  | 
 17.378  | 
||
| 
 5000  | 
 3.683  | 
 20.694  | 
||
| 
 10000  | 
 8.709  | 
 47.536  | 
||
| 
 案例1:测试结果(响应时间秒) -先调用ADO.net,然后调用 DataDirect  | 
||||
| 
 SP执行次数  | 
 DataDirect  | 
 ADO.net  | 
||
| 
 1000  | 
 1.061  | 
 4.335  | 
||
| 
 2000  | 
 2.064  | 
 14.088  | 
||
| 
 3000  | 
 2.279  | 
 11.602  | 
||
| 
 4000  | 
 3.876  | 
 17.518  | 
||
| 
 5000  | 
 3.373  | 
 20.778  | 
||
| 
 10000  | 
 6.421  | 
 44.504  | 
||

结论 :
1. DataDirect响应时间很少,利用DataDirect运行的查询的性能有很大改善
2. 存储过程执行次数加大,性能差距加大
3 DataDirect对oracle和大数据传出性能更突出
3. 4. DataDirect在Oracle,Sybase和DB2上支持Entity framework 4和Nhibernate。
5. 最新的DataDirect (v3.5)并不支持SQL Server上的EF和N-hibernate(这个非常令人意外,有待进一步确认),它只支持传统的ADO.net和Enterprise Library 。
6. 需要测试其他应用情况(例如增删改),需要测试包括ASP.net Web应用程序和并发调用的性能比较。
7. 就系统级别来说,利用DataDirect能提高多少性能有待进一步评估。(希望感兴趣的读者可以补充这部分)
程序代码:
http://files.cnblogs.com/huyq2002/Topic1DataDirect.zip
P.S.(1)请修改代码中的connectionStrDataDirect和connectionStrADO的数据连接字符串去连接正确的sql server数据库。
(2)数据库脚本不包含数据插入代码,可以利用循环插入测试数据。
(3) 请下载PROGRESS_DATADIRECT_CONNECT_ADO.NET_3.5.0_WIN.zip并安装(开发需要部署不需要,安装过程较慢)
http://www.datadirect.com/product-downloads/connect-ado-net.html
(4)示例代码的data direct组件是试用版的,可能会有失效问题。
有关DataDirect,请参考链接 http://www.datadirect.com/