【Frank.Xu】.net深入学习笔记(1):dataset和sqldatareader性能差异深入剖析与测试

2009年已经来临,中国的新春佳节就要到来.首先祝各位新年快乐,牛年大吉~~此篇文章作为我blog的第一篇文章,写出来希望能与大家一起分享经验,交流技术.

    dataset和sqldatareader的比较的文章和帖子网上已经很多,我也看了很多前辈的随笔.自己在面试和实际工作中也遇到这样的问题.但是始终是没深入进行学习.最近在工作空闲之余,特地查阅了一些文章,也包括msdn的官方文档.自己建立数据库和测试程序,对dataset和sqldatareader做了比较.

   首先关于两者比较主流的观点就是:

1.datareader使用时始终占用sqlconnection,在线操作数据库.dataset则是将数据一次性加载在内存中.支持数据库访问的断开连接模型.

2.datareader每次只在内存中加载一条数据,节约内存.dataset将数据全部加载在内存中.比较消耗内存.

3.datareader单向只读.dataset支持查询\修改\删除等操作,比较灵活.

4.datareader与 sqlcommand搭配.dataset与dataadapter 结合使用.

   为什么会这样呢?我们就来分析一下具体的原因.查看一下msdn关于 两者的不同描述:

1>sqldatareader 类提供一种从 sql server 数据库读取行的只进流的方式。无法继承此类。 命名空间:  system.data.sqlclient程序集:  system.data(在 system.data.dll 中).可以使用 ado.net datareader 从数据库中检索只读、只进的数据流。查询结果在查询执行时返回,在并存储在客户端的网络缓冲区中,直到您使用 datareaderread 方法对它们发出请求。使用 datareader 可以提高应用程序的性能,原因是它只要数据可用就立即检索数据,并且(默认情况下)一次只在内存中存储一行,减少了系统开销。

2>dataset 对象是支持 ado.net 的断开式、分布式数据方案的核心对象。dataset 是数据的内存驻留表示形式,无论数据源是什么,它都会提供一致的关系编程模型。它可以用于多种不同的数据源,用于 xml 数据,或用于管理应用程序本地的数据。dataset 表示包括相关表、约束和表间关系在内的整个数据集。下图将显示 dataset 对象模型。

  

     从上面的描述可以看出,datareader和dataset具有不同的结构模型.在数据的方式处理上也存在显著的差别.sqldatareader 会避免创建不必要的对象或复制不必要的数据.dataset 可以表示完整的数据模型,包括表格、约束条件和表关系.在对象的创建和销毁等环节需要消耗更多的资源,因此在性能上也稍显逊色.因此很多文章得出的结论也是在只进行读数据操作的情况下,datareader的性能要强于dataset.但是很多文章都没有相应的测试,就盲目下结论.

      但是好奇心理的驱使使我很想来做个试验来验证一下这个结论,到底datareader比dataset在查询数据的时候,性能会不会胜出,如果前者更优的话那么会超出多少?我自己写了个小程序,自己建立的数据库进行了实验.  实验测试环境如下:

硬件:

cpu

intel t2300 1.66ghz

内存

kingston ddr2 667 1g

硬盘

80g 5400 8m

软件:

操作系统

windows server 2003

数据库系统

sql server 2005 enterprise

数据规模

1000000条数据

数据库表结构

test

名称

类型

备注

id

int

标志\聚集索引

name

nvarchar(50)

非聚集索引

birthday

datetime

生日

height

int

身高

sex

int

性别

address

nvarchar(100)

地址

lastlogintime

datetime

非聚集索引

具体的实验程序c#代码如下,使用了using system.data.sqlclient;
using system.diagnostics;两个namespace下的类,stopwatch对象用来进行计时.

测试dataset的代码:

 

contractedblock.gif expandedblockstart.gif code
<!--

code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/

--&gt 1 using (sqlconnection conn = new sqlconnection("data source=127.0.0.1;initial catalog=test;integrated security=true"))
 2expandedblockstart.gifcontractedblock.gif            {
 3                stopwatch st = new stopwatch();
 4                st.start();
 5                conn.open();
 6                sqldataadapter da = new sqldataadapter(squery, conn);
 7                st.stop();
 8                //textbox3.text = st.elapsedmilliseconds.tostring();
 9
10                st.start();
11                dataset ds = new dataset("test");
12                da.fill(ds);
13                st.stop();
14                long ltimes = st.elapsedmilliseconds;
15                //textbox1.text = ltimes.tostring();
16                conn.close();
17expandedsubblockstart.gifcontractedsubblock.gif                /**////textbox3.text = sizeof(dataset);
18            }

19            

 

测试datareader的代码:

 

contractedblock.gif expandedblockstart.gif code
<!--

code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/

--&gt 1 using (sqlconnection conn = new sqlconnection("data source=127.0.0.1;initial catalog=test;integrated security=true"))
 2expandedblockstart.gifcontractedblock.gif            {
 3
 4                stopwatch st = new stopwatch();
 5                st.start();
 6                conn.open();
 7                sqlcommand comm = new sqlcommand(squery, conn);
 8                st.stop();
 9                textbox4.text = st.elapsedmilliseconds.tostring();
10                st.start();
11                sqldatareader reader = comm.executereader();
12                while (reader.read())
13expandedsubblockstart.gifcontractedsubblock.gif                {
14                    
15                }

16                st.stop();
17                long ltimes = st.elapsedmilliseconds;
18                textbox2.text = ltimes.tostring();
19                conn.close();
20                //textbox4.text = sizeof(sqldatareader);
21            }

测试语句和时间ms分别如下:

语句

datareader费时

dataset费时

string squery = "select * from dbo.test where id <= 1"

0ms

0ms

string squery = "select * from dbo.test where id <=10"

1ms

1ms

string squery = "select * from dbo.test where id <=100"

2ms

3ms

string squery = "select * from dbo.test where id <=1000"

5ms

6ms

string squery = "select * from dbo.test where id <=10000"

8ms

50ms

从试验结果分析可以得出如下结论:

1.在查询数据量很少的情况下100条内,datareader和dataset几乎没有什么明显的性能差别.

2.数据量过大,接近10000条的时候的数据查询,datareader的性能要明显优于dataset.

对于两者的性能对比,不应该轻易下结论,除了参考实验设备,也要考虑实际的数据规模.

具体项目应用中,选择适合具体需求的对象进行数据处理,才能有效的提高系统的性能.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15783504/viewspace-557535/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/15783504/viewspace-557535/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值