究竟哪种取数据的方式最快?
對于DataSet,DataReader,sql語句取數據,存儲過程取數據這些常見的方式,它們之間的效率問題,網上的評論非常多,而且又不是十分地統一,為了證明它們到底"有多快",我進行了如下測試:
測試一:
主題:DataSet?? VS? DataReader?
數據量:10萬數據的測試表
連接方式:本機
先進行數據表DataTable的裝載測試:
?
DataTable+sql語句裝載 ?1?????????????SqlConnection?conn?=?new?SqlConnection("server=.;database=Test;uid=Test;pwd=test;");?2?????????????DataTable?resultDt?=?new?DataTable();
?3?????????????resultDt.Columns.Add(new?DataColumn("Id",?typeof(int)));
?4?????????????resultDt.Columns.Add(new?DataColumn("TestData1",typeof(string)));
?5?????????????resultDt.Columns.Add(new?DataColumn("TestData2",?typeof(string)));????????????
?6?????????????string?queryStr?=?"select?*?from?TestTable";//構建數據表,連接對象及查詢語句
?7?????????????Stopwatch?watch1?=?new?Stopwatch();//方式一:DataSet方式裝載
?8?????????????watch1.Start();
?9?????????????SqlDataAdapter?sda?=?new?SqlDataAdapter(queryStr,?conn);
10?????????????DataSet?ds?=?new?DataSet();
11?????????????sda.Fill(ds);
12?????????????resultDt?=?ds.Tables[0];
13?????????????watch1.Stop();
14?
15?
16?????????????Stopwatch?watch2?=?new?Stopwatch();//方式二:DataReader方式裝載
17?????????????watch2.Start();
18?????????????SqlCommand?cmd?=?new?SqlCommand(queryStr,?conn);
19?????????????conn.Open();
20?????????????SqlDataReader?sdr?=?cmd.ExecuteReader();
21?????????????while?(sdr.Read())?{
22?????????????????DataRow?dr?=?resultDt.NewRow();
23?????????????????dr["Id"]?=?sdr["id"];
24?????????????????dr["TestData1"]?=?sdr["TestData1"];
25?????????????????dr["TestData2"]?=?sdr["TestData2"];
26?????????????????resultDt.Rows.Add(dr);
27?????????????}
28?????????????sdr.Close();
29?????????????conn.Close();
30?????????????watch2.Stop();
31?
32?????????????Console.WriteLine("DataSet??? method,Reflection:?"?+?watch1.Elapsed);
33?????????????Console.WriteLine("DataReader method,Reflection:?"?+?watch2.Elapsed);
34?????????????Console.ReadLine();
?測試結果:
DataSet??? method,Reflection: 00:00:01.0080464
DataReader method,Reflection: 00:00:01.1056812?
然后,我們把這個語句放進存儲過程,再測試速度:
?存儲過程中語句也就是剛剛的查詢語句:
?
DataTable+存儲過程裝載 ?1?????????????SqlConnection?conn?=?new?SqlConnection("server=.;database=Test;uid=Test;pwd=test;");?2?????????????DataTable?resultDt?=?new?DataTable();
?3?????????????resultDt.Columns.Add(new?DataColumn("Id",?typeof(int)));
?4?????????????resultDt.Columns.Add(new?DataColumn("TestData1",?typeof(string)));
?5?????????????resultDt.Columns.Add(new?DataColumn("TestData2",?typeof(string)));
?6?
?7?
?8?
?9?????????????SqlCommand?cmd?=?new?SqlCommand();
10?????????????cmd.CommandType?=?CommandType.StoredProcedure;
11?????????????cmd.CommandText?=?"GetTestData";
12?????????????cmd.Connection?=?conn;
13?
14?????????????Stopwatch?watch1?=?new?Stopwatch();
15?????????????watch1.Start();????????????
16?????????????SqlDataAdapter?sda?=?new?SqlDataAdapter(cmd);
17?????????????DataSet?ds?=?new?DataSet();
18?????????????sda.Fill(ds);
19?????????????resultDt?=?ds.Tables[0];
20?????????????watch1.Stop();
21?
22?
23?????????????Stopwatch?watch2?=?new?Stopwatch();
24?????????????watch2.Start();????????????
25?????????????conn.Open();
26?????????????SqlDataReader?sdr?=?cmd.ExecuteReader();
27?????????????while?(sdr.Read())
28?????????????{
29?????????????????DataRow?dr?=?resultDt.NewRow();
30?????????????????dr["Id"]?=?sdr["id"];
31?????????????????dr["TestData1"]?=?sdr["TestData1"];
32?????????????????dr["TestData2"]?=?sdr["TestData2"];
33?????????????????resultDt.Rows.Add(dr);
34?????????????}
35?????????????sdr.Close();
36?????????????conn.Close();
37?????????????watch2.Stop();
38?
39?????????????Console.WriteLine("DataSet????method,Reflection:?"?+?watch1.Elapsed);
40?????????????Console.WriteLine("DataReader?method,Reflection:?"?+?watch2.Elapsed);
41?????????????Console.ReadLine();
?運行結果為:
DataSet??? method,Reflection: 00:00:01.0025863
DataReader method,Reflection: 00:00:01.1531541
小結:不管是SQL語句方式,還是存儲過程方式,把數據裝進DataTable,DataSet方式都比DataReader要快一點點.要是不裝載到DataTable呢,情況會不會有所改變呢?
帶著這個問題,我有了如下測試:
?
DataReader不裝進DataTable ?1?????????????SqlConnection?conn?=?new?SqlConnection("server=.;database=Test;uid=Test;pwd=test;");?2?????????????DataTable?resultDt?=?new?DataTable();
?3?????????????resultDt.Columns.Add(new?DataColumn("Id",?typeof(int)));
?4?????????????resultDt.Columns.Add(new?DataColumn("TestData1",?typeof(string)));
?5?????????????resultDt.Columns.Add(new?DataColumn("TestData2",?typeof(string)));
?6?????????????string?queryStr?=?"select?*?from?TestTable";
?7?????????????Stopwatch?watch1?=?new?Stopwatch();
?8?????????????watch1.Start();
?9?????????????SqlDataAdapter?sda?=?new?SqlDataAdapter(queryStr,?conn);
10?????????????DataSet?ds?=?new?DataSet();
11?????????????sda.Fill(ds);
12?????????????resultDt?=?ds.Tables[0];
13?????????????watch1.Stop();
14?
15?
16?????????????Stopwatch?watch2?=?new?Stopwatch();
17?????????????watch2.Start();
18?????????????SqlCommand?cmd?=?new?SqlCommand(queryStr,?conn);
19?????????????conn.Open();
20?????????????SqlDataReader?sdr?=?cmd.ExecuteReader();
21?????????????int?i?=?0;
22?????????????while?(sdr.Read())
23?????????????{
24?????????????????i++;
25?????????????}
26?????????????sdr.Close();
27?????????????conn.Close();
28?????????????watch2.Stop();
29?
30?????????????Console.WriteLine("DataSet????method,Reflection:?"?+?watch1.Elapsed);
31?????????????Console.WriteLine("DataReader?method,Reflection:?"?+?watch2.Elapsed);
32?????????????Console.ReadLine();
33?
?運行結果:
DataSet??? method,Reflection: 00:00:00.9876266
DataReader method,Reflection: 00:00:00.1093267
情況有了改變.但現實中,DataReader不裝載到任何對象中的情況還是非常少的.例如,我們經常把這些數據裝到List<>對象中,效率究竟怎么樣?
?
List<>裝載 ?1?????????????SqlConnection?conn?=?new?SqlConnection("server=.;database=Test;uid=Test;pwd=test;");?2?????????????List<TestData>?resultDt?=?new?List<TestData>();????????????
?3?????????????TestData?td?=?null;
?4?????????????string?queryStr?=?"select?*?from?TestTable";
?5?????????????Stopwatch?watch1?=?new?Stopwatch();
?6?????????????watch1.Start();
?7?????????????SqlDataAdapter?sda?=?new?SqlDataAdapter(queryStr,?conn);
?8?????????????DataSet?ds?=?new?DataSet();
?9?????????????sda.Fill(ds);????????????
10?????????????foreach?(DataRow?dr?in?ds.Tables[0].Rows)?{
11?????????????????td?=?new?TestData();
12?????????????????td.Id?=?Convert.ToInt32(dr["Id"]);
13?????????????????td.TestData1?=?dr["TestData1"].ToString();
14?????????????????td.TestData2?=?dr["TestData2"].ToString();
15?????????????????resultDt.Add(td);
16?????????????}
17?????????????watch1.Stop();
18?
19?
20?????????????Stopwatch?watch2?=?new?Stopwatch();
21?????????????watch2.Start();
22?????????????SqlCommand?cmd?=?new?SqlCommand(queryStr,?conn);
23?????????????conn.Open();
24?????????????SqlDataReader?sdr?=?cmd.ExecuteReader();????????????
25?????????????while?(sdr.Read())
26?????????????{
27?????????????????td?=?new?TestData();
28?????????????????td.Id?=?Convert.ToInt32(sdr["Id"]);
29?????????????????td.TestData1?=?sdr["TestData1"].ToString();
30?????????????????td.TestData2?=?sdr["TestData2"].ToString();
31?????????????????resultDt.Add(td);
32?????????????}
33?????????????sdr.Close();
34?????????????conn.Close();
35?????????????watch2.Stop();
36?
37?????????????Console.WriteLine("DataSet????method,Reflection:?"?+?watch1.Elapsed);
38?????????????Console.WriteLine("DataReader?method,Reflection:?"?+?watch2.Elapsed);
39?????????????Console.ReadLine();
?
?運行結果:
DataSet??? method,Reflection: 00:00:01.1134010
DataReader method,Reflection: 00:00:00.4901601
小結:
DataSet中包含了DataTable的集合,所以,在SqlDataAdapter.Fill(ds)的過程中,其實已經進行了一次數據裝載,再裝載到其它對象,等于是進行了2次裝載.故爾速度稍慢.
要將數據裝到DataTable時,DataReader比DataSet要慢,而裝載到List<>對象時,DataReader要比DataTable快至少一倍.
?
我目前用的是2005的測試環境,下次我會到2008環境下測試延遲加載,看看情況會有什么不同.?
?
?
轉載于:https://www.cnblogs.com/CoreCaiNiao/archive/2009/12/24/1631514.html
總結
以上是生活随笔為你收集整理的究竟哪种取数据的方式最快?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: swing中如何将jtable中的数据导
- 下一篇: [转]CPoint+CSize+CRec