APP下载

基于ADO.NET的数据访问编码优化

2013-06-27蔡朝晖付丹丹

大庆师范学院学报 2013年6期
关键词:驱动程序事务语句

蔡朝晖,付丹丹,苏 丹

(大庆师范学院计算机科学与信息技术学院,黑龙江大庆163712)

基于ADO.NET的数据访问编码优化

蔡朝晖,付丹丹,苏 丹

(大庆师范学院计算机科学与信息技术学院,黑龙江大庆163712)

分析了数据库应用程序在运行中出现的性能问题,进而讨论了基于ADO.NET的数据库访问技术的优化原则,并针对具体的应用程序设计编写了相应的优化数据访问代码。

数据访问;数据库中间件;性能优化;ADO.NET技术

0 引言

随着计算机硬件变得更快更廉价,大多数数据库应用程序通过网络与数据库进行通信,而不再是直接通过单个计算机中的内部进程进行通信。与此同时,计算机软件则需要提供在应用程序和数据库之间的连接,即所谓的数据库中间件,因此企业出现了对数据库连接标准的需求,通用的应用程序编程接口(application programming interface,API)应运而生。例如ODBC(Open Database Connectivity,开放式数据库连接)的出现,解决了开发人员对于不同数据源Microsoft SQL Server、Oracle和IBM DB2等的数据访问的统一接口问题。

随着数据库连接标准的出现,数据库驱动程序被添加到数据库中间件层,即数据库驱动程序处理基于标准的API函数调用,向数据库提交SQL(Structured Query Language,结构化查询语言)请求,并向应用程序返回结果。但同时数据访问中间件的使用,也为应用程序的性能问题添加了新的隐患。

目前,开发人员面临的系统性能问题是:即使数据库调试得很好,数据库应用程序的运行情况却并不总是尽如人意。其主要原因是:相比于之前处理请求时间大多用在DBMS(Data Base Management System,数据库管理系统)上,近几年,应用系统处理请求时间的75%~95%则花费在了数据库中间件上[1]。

在本文中,我们讨论了基于ADO.NET(ActiveX Data Objects for the.NET)的数据库访问技术的优化原则和方法,并针对具体教学项目案例《毕业论文管理系统》设计编写了相应的数据访问代码。

1 应用程序性能问题分析

数据库应用程序中的性能问题,一般由于以下4个方面原因引起的[1]:

1)网络通信数据包的容量设定

网络常见性能问题是完成一个操作需要的往返次数。在应用程序和数据库之间发送的数据包数越少,意味着在数据库和应用程序之间的往返次数越少。

2)数据库驱动程序的选择

在数据库应用程序部署中,选择使用哪个驱动程序,对性能有很大的影响。一个好的数据库驱动程序,能够更加高效地处理连接池和内存管理。

3)环境配置

内存的适时分配与释放、服务器端与客户端彼此操作系统的字节顺序是否匹配等都会影响应用程序性能;另外,在当前虚拟化的新趋势下,硬件资源的使用很容易达到极限,检测产生硬件(内存、磁盘I/O、CPU以及网络适配器)瓶颈的原因变得更加困难。

4)数据库应用程序编码不良

如果应用程序代码的效率不高,应用程序向数据库中间件发送数据请求的性能就会降低。例如对事务管理的提交方式,如果使用默认的自动提交模式就会对应用程序造成严重的性能限制,因为对于大多基于标准的应用程序,默认的事务模式需要数据库驱动程序在每个API请求之后处理昂贵的Commit操作。

2 基于ADO.NET的性能优化原则

2.1 ADO.NET概述

ADO.NET是一组用于和数据源进行交互的面向对象类库,用于读写数据库,是Microsoft希望在.NET编程环境中优先使用的数据访问接口。访问过程如图1所示。

图1 ADO.NET数据访问过程

2.2 ADO.NET数据访问模式

在ADO.NET组件中包含两个核心组件,分别是.NET Framework数据提供程序和数据集DataSet。

基于ADO.NET的客户端应用程序有两种数据访问模式,即通过DataSet对象访问数据模式和通过DataReader对象访问数据模式。如图2所示。

图2 ADO.NET数据访问模式

ADO.NET的两种数据访问模式本身就为应用程序提供了可优化选择:使用DataSet对象是数据集断开式(也称非连接式)数据访问模式,使用DataReader对象则是连接式数据访问模式。

其中的DataSet对象是ADO.NET技术基于ADO技术的重大变化和革新,旨在解决Web应用程序的松耦合特性以及其在本质上互不关联的特性[2]。

如图2所示,DataSet对象通过DataAdepter对象访问数据库,它不直接对数据库进行访问,从而实现了断开式的数据库访问。DataSet对象代表数据库的内存缓存[2],由于其独立于数据库,所以配合了连接池的管理方式,在数据库连接上为系统性能优化提供了保证。

2.3 ADO.NET访问数据库方法及步骤

(1)使用连接对象connection连接数据源;

(2)使用命令对象Command执行SQL语句或存储过程操纵数据库;

(3)使用数据读取器对象DataReader读取数据,或者使用数据集对象DataSet和数据适配器对象DataAdapter访问数据库。

2.4 性能优化通用原则

在应用程序开发中,对ADO.NET应用程序进行性能优化是一件很复杂的事情。首先,当代码运行缓慢时,数据提供程序是不会抛出异常进行通知的;其次,因为不同数据提供程序之间,编程概念有一定的差异,编写.NET应用程序比编写ODBC或JDBC应用程序更复杂。

所以,所谓的性能优化通用原则[1],是指我们所设计的数据访问编码,它们具体实现了以下4个目标中的一个或多个:

(1)降低网络通信量;

(2)限制磁盘I/O;

(3)优化应用程序和驱动程序之间的交互;

(4)简化查询。

3 ADO.NET编码优化建议

3.1 使用连接池管理连接

数据库连接可能需要付出较昂贵的时间和资源成本,为了缓解这个成本问题,许多数据提供者都支持连接池(Connection Pooling)。默认情况下,ADO.NET中启用连接池,除非以显式形式禁用,否则,连接在应用中打开和关闭时,池进程将对连接进行优化。

优化原理[2]:连接池可以减少新连接需要打开的次数。池进程保持物理连接的所有权。通过为每个给定的连接配置保留一组连接来管理连接。只要用户在连接上调用Open,池进程就会检查池中是否有可用的连接。如果某个池连接可用,会将该连接返回给调用者,而不是打开新连接。应用程序在该连接上调用Close时,池进程会将该连接返回到活动连接池中,而不是真正关闭连接。连接返回到池中后,即可在下一个Open调用中使用。

3.2 使用手动提交模式管理事务

提交或回滚事务是比较缓慢的,因为涉及到磁盘I/O,同时潜在地需要大量的网络往返,通常建议在应用程序中关闭自动提交模式,并同时使用手动提交模式;另外,除非必须使用分布式事务,否则应使用本地事务。

优化原理:自动提交模式下,每次成功操作之后,数据提供程序就向数据库发送一个提交请求,需要进行一次网络往返;而使用手动提交模式,应用程序可以控制何时提交数据库工作,避免了不必要的事务自动提交。至于优先选择本地事务模型,是由于本地事务访问和更新位于单个数据库中的数据,而分布式事务访问和更新位于多个数据库中的数据,事务须协调这些数据库。

3.3 选择合适的SQL语句、程序和方法

(1)选择执行SQL语句的Command对象方法

使用Command对象方法执行SQL语句时,有选择地使用以下方法:ExecuteNonQuery、ExecuteReader、ExecuteScalar,可以得到最佳性能。

执行不检索数据的SQL语句(如Update、Insert、Delete),使用ExecuteNonQuery方法,因为此方法只返回影响记录数量,不返回实际记录;如果SQL语句检索单个数值(总数或个数),使用ExecuteScalar方法,因为此方法返回结果集中第一条记录的第一列。

(2)选择使用语句或预先编译的语句

如果正在使用只会执行一次的SQL语句,选择使用语句,因为该语句不会被放入语句池,这样可以避免相应的在池中查找该语句的负担。当SQL语句执行频率较高时,建议使用预先编译的Command对象。

(3)使用参数数组或批处理

当更新大量数据时,可以使用参数数组或SQL语句的批处理。尽管参数数组使用更多的CPU循环,但是通过减少网络往返次数可以提升性能。

(4)使用批量加载

如果有大量数据需要插入到数据库表中,使用批量加载比参数数组更快。使用批量加载时,记录在一个连续的流中从数据库客户端发送到数据库,从而不会生成额外的网络往返;此外,当执行批量加载时,数据库能够优化插入记录的方式。但使用批量加载可能会忽略参照完整性,从而引起数据的一致性问题。

(5)使用纯托管提供程序

使用纯托管代码,.NET程序集运行于CLR(Command Language Runtime,公共语言运行库)内部,与数据提供程序连接到非托管代码或在CLR外部运行时相比,内部调用的相关开销会降低5%~100%。尤其是应用程序服务器运行繁忙时,性能对比更明显。

3.4 控制检索数据量

(1)设计应用程序从select列表中排除长数据

通过网络检索长数据速度比较慢,并且需要消耗大量的资源。而且大多用户实际上不希望查看长数据。以下列出尽量避免使用的长数据类型:大XML数据、长文本、长二进制数据、Clob以及Blob。

(2)限制检索数据量

限制在驱动程序和数据库服务器之间的网络通信量,可以通过确保select语句及其所使用where子句限制检索返回结果的数据量;当不能避免检索会产生大量网络通信量时,应用程序可以限制通过网络发送的记录数量,同时降低通过网络发送的每条记录的大小,从而控制数据库向驱动程序发送的数据量。

(3)选择处理效率比较高的数据类型

处理速度从最快到最慢的数据类型:binary(二进制),int、smallint、float(32位整数、16位整数、64位小数),decimal(十进制),timestamp(时间戳),char(字符)。

图3显示了当属性列分别定义为64位整数类型与decimal(20)类型时,每秒返回的记录数量的比较。

图3 不同数据类型的性能比较

4 数据访问编码实例及优化分析

针对《毕业论文管理系统》中的“修改选题”功能,采用了上述优化建议,规避了数据访问中影响应用程序性能的主要问题,设计编写了相关的优化测试代码。其优化的主要方面包括:

(1)及时关闭不使用的数据库连接,当然这些连接还保持在连接池中;

(2)设置管理事务的提交模式为手动提交,其中设计相关的完整操作“修改选题”在同一事务中;

(3)使用纯托管提供程序,即使用SQL Server专用的内置.NET数据提供者对基础功能进行直接访问;

(4)选用DataReader对象查看“论文选题”情况;

(5)选用DataSet对象完成“修改题目”操作的相关数据库表数据的更新,并使用显示方式更新数据。

4.1 编码实例

//以下代码用C#语言编写

说明:①连接字符串中设置Integrated Security=SSPI(集成安全性)时,可以使用windows身份验证;连接字符串中设置Connect Timeout=5,连接被销毁前,此连接在连接池中生存的最短时间为5秒;连接字符串中设置MultipleActiveResultSets=true,为数据连接复用。

②交互操作部分代码略去。

4.2 编码优化分析

(1)使用using指令引用专用内置的.NET数据提供程序;

(2)使用try/catch块处理连接异常,同时在finally块中显示关闭连接,确保及时关闭不使用的连接,避免等待垃圾收集器清除不用连接的时间,而间接影响其他连接的等待时间;

(3)使用Transaction对象处理一个功能的两部分操作,即通过事务管理,确保数据库的一致性和完整性。同时使用事务的显示提交或回滚,避免了不必要的事务自动提交;

(4)检索大量只读数据时,选DataReader对象;(5)插入、更新或删除数据时,选用DataSet对象。

5 结语

数据库应用程序设计会直接影响所开发的应用程序性能,软件设计人员和开发人员应特别注意这一点。由于为了收集数据库的相关信息,应用程序经常需要通过代码建立连接,而建立连接对性能的影响非常大,所以为了达到最好的性能,必须考虑相关的数据库应用程序设计。

本文编码优化涉及的几个关键的应用程序功能区包括:数据库连接配置、事务提交模式、SQL语句执行以及数据检索设计。

[1]John Goodson,Robert A.Steward.数据访问宝典[M].北京:清华大学出版社,2010:155-176.

[2]龚根华,王炜立.ADO.NET数据访问技术[M].北京:清华大学出版社,2012:25-33,74-75,87-138.

[3]Shawn Eildermuth,Mark Blomsma,Jim Wightman.ADO.NET应用程序开发[M].北京:清华大学出版社,2010:1-33,105-120.

蔡朝晖(1968-),女,黑龙江大庆人,大庆师范学院计算机科学与信息技术学院副教授,博士生,从事数据库与知识库研究。

大庆师范学院教学改革研究资助项目(JY1230)。

G642

A

2095-0063(2013)06-0026-05

2013-08-21

猜你喜欢

驱动程序事务语句
基于分布式事务的门架数据处理系统设计与实现
重点:语句衔接
河湖事务
计算机硬件设备驱动程序分析
基于OCC-DA-MCP算法的Redis并发控制
如何搞定语句衔接题
基于MPC8280的CPU单元与内部总线驱动程序设计
移动实时环境下的数据一致性研究
作文语句实录
妙用鼠标驱动