DataSet和DataReader

來源:互聯網
上載者:User

在網上關於DataSet和DataReader的使用的討論很多,大都是討論到底該使用DataSet還是DataReader,我也發表一下我的看法。先看一下DataSet和DataReader的區別,DataSet實際上是一個離線資料集,DataSet不用保持資料庫連接,而 DataReader需要保持資料庫連接,這應當是兩者的本質區別,分別對應的ava中的CachedRowSet 和ResultSet,所以兩者各有各的用處,DataSet使用前必須填充,所以必須從記憶體中開闢記憶體儲存DataSet的內容,而 DataReader的使用必須使資料庫連接有效,但是不必開闢記憶體儲存所有的資料,所以在資料量較小時,使用DataSet可以提升效能,因為所有的資料都在記憶體中操作,但資料量較大時(“較大“的標準不一,一般上千條的資料應當稱作較大了吧)使用DataReader就有優勢,因為 DataReader每次讀取都是利用自身保持的資料庫連接從資料庫中動態讀取,不會將大量的資料一下裝入記憶體(也就是所謂的懶裝入 lazyloding),但缺點是唯讀,並且是僅向前的,如果你要多次使用同一個資料,還是得先緩衝該資料,否則讀取一次後將不能重複讀取,所以建議就是資料量較少的時候用DataSet,而資料量大時使用DataReader當然,不管使用那個,都應當盡量將查詢數量降到最低,只有這樣才能做到高效使用,另外,如果你針對每一條資料都需要一個耗時操作的話,要避免使用DataReader,因為資料庫連接資源是非常寶貴的,一個伺服器串連池中一般就十幾個串連罷了,要是每人都保持串連的話,用不了多久就會耗光。

 

DataSet和SqlDataReader效能測試轉自:http://www.cnblogs.com/frank_xl/archive/2009/01/15/1375976.html

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的代碼:

Code
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的代碼:

Code
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分別如下:

語句 DataSet費時 DataReader費時
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.
對於兩者的效能對比,不應該輕易下結論,除了參考實驗裝置,也要考慮實際的資料規模.
具體項目應用中,選擇適合具體需求的對象進行資料處理,才能有效提高系統的效能.
          本文的測試環境和結果可能存在偏差,但是希望能給大家帶來一些協助,一起交流學習.謝謝.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.