.NET深入学习笔记(1):DataSet和SqlDataReader性能差异深入剖析与测试(1)

简介:




声明:这篇文章可能存在错误,我对于 DataSet和SqlDataReader概念的理解有误,当时主要是针对网络上一个面试的题目做出的,测试。我在核实资料后与验证代码后会做出更新。

    我已经使用Reflector查看了SQLDataAdapter类型的Fill方法以及SqlCommand.ExecuteReader 方法代码。确实有使用DataReader的地方。他们是真正负责处理查询并装在数据。DataReader和DataSet应该都是数据容器。做个类比的话,应该是茶壶和茶杯的关系。 至于查询数据,除了取决于容器,还和具体负责查询和装载数据的类有关系。 我文章的标题,应该说是有问题的,这种比较忽略了一个数据查询和装载的过程。有不合理的地方。现在更正。
 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 从数据库中检索只读、只进的数据流。查询结果在查询执行时返回,在并存储在客户端的网络缓冲区中,直到您使用  DataReader 的  Read方法对它们发出请求。使用  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的代码:
 1   using  (SqlConnection conn  =   new  SqlConnection( " Data Source=127.0.0.1;Initial Catalog=Test;Integrated Security=True " ))
 2              {
 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();
17                ///textBox3.Text = sizeof(DataSet);
18            }

19             
 
测试 DataReader的代码:
 

 1 using (SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Test;Integrated Security=True"))
 2            {
 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())
13                {
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.
对于两者的性能对比,不应该轻易下结论,除了参考实验设备,也要考虑实际的数据规模.
具体项目应用中,选择适合具体需求的对象进行数据处理,才能有效的提高系统的性能.
          本文的测试环境和结果可能存在偏差,但是希望能给大家带来一些帮助,一起交流学习.谢谢.
【2】补充:
DataAdapter的Fill方法的源码,我们使用反射器查看,代码如下:


 本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/320999,如需转载请自行联系原作者



相关文章
|
2月前
|
机器学习/深度学习 人工智能 监控
提升软件质量的关键路径:高效测试策略与实践在软件开发的宇宙中,每一行代码都如同星辰般璀璨,而将这些星辰编织成星系的过程,则依赖于严谨而高效的测试策略。本文将引领读者探索软件测试的奥秘,揭示如何通过精心设计的测试方案,不仅提升软件的性能与稳定性,还能加速产品上市的步伐,最终实现质量与效率的双重飞跃。
在软件工程的浩瀚星海中,测试不仅是发现缺陷的放大镜,更是保障软件质量的坚固防线。本文旨在探讨一种高效且创新的软件测试策略框架,它融合了传统方法的精髓与现代技术的突破,旨在为软件开发团队提供一套系统化、可执行性强的测试指引。我们将从测试规划的起点出发,沿着测试设计、执行、反馈再到持续优化的轨迹,逐步展开论述。每一步都强调实用性与前瞻性相结合,确保测试活动能够紧跟软件开发的步伐,及时适应变化,有效应对各种挑战。
|
2月前
|
监控 测试技术 PHP
性能和压力测试
【10月更文挑战第10天】性能和压力测试
114 60
|
2月前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
213 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
2月前
|
测试技术 Python
自动化测试项目学习笔记(四):Pytest介绍和使用
本文是关于自动化测试框架Pytest的介绍和使用。Pytest是一个功能丰富的Python测试工具,支持参数化、多种测试类型,并拥有众多第三方插件。文章讲解了Pytest的编写规则、命令行参数、执行测试、参数化处理以及如何使用fixture实现测试用例间的调用。此外,还提供了pytest.ini配置文件示例。
35 2
|
2月前
|
测试技术 Python
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
本文主要介绍了自动化测试中setup、teardown、断言方法的使用,以及unittest框架中setUp、tearDown、setUpClass和tearDownClass的区别和应用。
65 0
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
|
2月前
|
测试技术 PHP 开发工具
php性能监测模块XHProf安装与测试
【10月更文挑战第13天】php性能监测模块XHProf安装与测试
33 0
|
3月前
|
敏捷开发 安全 测试技术
软件测试的艺术:确保质量与性能的平衡之道
【9月更文挑战第24天】在软件开发的海洋中,测试是导航灯塔,指引着项目安全抵达质量的彼岸。本文将深入探讨软件测试的核心原则、方法论以及如何通过精心设计的测试策略来保障产品的可靠性和性能。我们将从测试的基础知识出发,逐步深入到高级测试技巧,最终展示如何通过实际案例来应用这些知识以确保软件的成功交付。
|
3月前
|
测试技术 Python
软件测试的艺术:确保质量与性能
【9月更文挑战第19天】在数字化时代,软件已成为我们生活的一部分。然而,随着软件复杂性的增加,如何确保其质量和性能成为了一个挑战。本文将探讨软件测试的重要性,介绍常见的测试类型和策略,并提供实用的代码示例来帮助读者更好地理解和应用这些测试方法。无论你是开发人员、测试工程师还是项目管理者,这篇文章都将为你提供有价值的见解和技巧。
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
44 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
64 0