dataset和datareader的区别

来源:互联网 发布:有赞 知乎 编辑:程序博客网 时间:2024/05/29 14:49

一、DataSet基本介绍

  1. Dataset表示一个数据集,是数据在内存中的缓存。 即是:DataSet是内存(关系型)数据库,它可以包括多个表以及表之间的相互关系,还有过滤查询等等。
  2. DataSet连接数据库时是非面向连接的,DataSet是将DB中的数据一次性加载到内存中,读取完数据以后放弃数据库连接,因为数据都在内存中,所以会比较消耗内存。
  3. DataSet支持查询\修改\删除等操作,比较灵活。


二、DataReader基本介绍

  1. DataReader使用时始终占用SqlConnection,在线操作数据库.
  2. DataReader每次只在内存中加载一条数据,节约内存,并且是只读的向前的,读完数据后由用户决定是否断开连接。
  3. DataReader单向只读.DataSet支持查询\修改\删除等操作,比较灵活.
  4. 运用DataReader类的理想条件: 你读取的数据必须是新的,所以在每次需要数据的时候,你都必须从数据库读取。


三、DataReader和DataSet两者读取数据性能比较

  1. DataReader比DataSet读取速度快,读取100条以下数据量时间差别很小,读取超过数千条数据差距非常明显。
  2. DataReader比DataSet占用内存特别小。DataSet容易产生大对象,对性能影响比较大。
  3. DataReader是在线读取数据需要自己关闭连接,并且高并发访问时要考虑数据库连接池是否够用的问题(一般只有在读取数千条数据持续占用数据库连接,并且并发访问量大的时候才会考虑这个问题)。


四、DataReader  使用关注点

  1. 当你在用DataReader类时,在关闭DataReader类前,与数据库的连接不会被释放回连接池。潜在的问题:在数千个请求之间(潜在的一个很小的延时都会造成)连接串并发访问量(且读取时间很长),从而就会有可能消耗完可用的数据库连接。


五、DataSet  使用关注点

  1. DataSet可以在读取所有的数据以后,并可以马上关闭与数据库的连接,将它返回到连接池,因此其它的请求就可以用这个连接了。
  2. 频繁创建DataSet必须要考虑内存占用和大对象两个问题。
  3. 在.Net中超过85K的对象都是大对象,频繁创建DataSet(临时性的)大对象,系统就需要花费的时间来运行垃圾回收。持续频繁的创建大对象然后又释放大对象对性能会有很大的负面影响。系统Cpu和Memory过山车似的曲线图很多是由于大对象产生的。


      关于.Net大对象的问题,参考如下资料
      http://www.cnblogs.com/yukaizhao/archive/2011/11/21/dot_net_gc_large_object_heap.html (中文)
      http://msdn.microsoft.com/en-us/magazine/cc534993.aspx (E文)

六、建议:

  1. 读取数据量很大且是动态的数据,建议使用DataReader
  2. 读取数据需要离线处理的或者需要重用读取的数据的,建议使用DataSet。
  3. 对于高并发访问数据库读取且数据量不大的,建议使用DataReader。注意使用完要关闭连接。
  4. 对应高并发访问数据库每次读取数据量比较大(超过85K),并且需要持续访问很长时间(这种场景必须做压力测试,对比两者的情况。),
    优先推荐DataReader,读取速度快(如果每次读取完都释放连接,连接池问题一般不会出现),如果选用DataSet的话,请考虑服务器Memory和大对象对Cpu的压力。


另外:
ExcecuteXmlReader()方法来得到一个XmlReader类(相当于XML版的DataReader),需要一个运用FOR XML子句的SQL Server查询,或者一个包含有效XML类型的字段(或者包含XML的ntext的字段)。

 

七、DataReader简单示例

 using (IDataReader idr = db.ExecuteReader(dbCommand)) //自动关闭idr

            {

                while (idr.Read())

                {

                   Code……

                }

            }        

或者

IDataReader rdr = db.ExecuteReader(dbCommand);

  while (idr.Read())

                {

                   Code……

                }

rdr.Close();

0 0