Przyjrzałem się temu również i po porównaniu metody SqlDataAdapter.Fill z funkcjami SqlDataReader.Load stwierdziłem, że metoda SqlDataAdapter.Fill jest ponad dwa razy szybsza od używanych przeze mnie zestawów wyników
Używany kod:
[TestMethod]
public void SQLCommandVsAddaptor()
{
long AdapterFillLargeTableTime, readerLoadLargeTableTime, AdapterFillMediumTableTime, readerLoadMediumTableTime, AdapterFillSmallTableTime, readerLoadSmallTableTime, AdapterFillTinyTableTime, readerLoadTinyTableTime;
string LargeTableToFill = "select top 10000 * from FooBar";
string MediumTableToFill = "select top 1000 * from FooBar";
string SmallTableToFill = "select top 100 * from FooBar";
string TinyTableToFill = "select top 10 * from FooBar";
using (SqlConnection sconn = new SqlConnection("Data Source=.;initial catalog=Foo;persist security info=True; user id=bar;password=foobar;"))
{
// large data set measurements
AdapterFillLargeTableTime = MeasureExecutionTimeMethod(sconn, LargeTableToFill, ExecuteDataAdapterFillStep);
readerLoadLargeTableTime = MeasureExecutionTimeMethod(sconn, LargeTableToFill, ExecuteSqlReaderLoadStep);
// medium data set measurements
AdapterFillMediumTableTime = MeasureExecutionTimeMethod(sconn, MediumTableToFill, ExecuteDataAdapterFillStep);
readerLoadMediumTableTime = MeasureExecutionTimeMethod(sconn, MediumTableToFill, ExecuteSqlReaderLoadStep);
// small data set measurements
AdapterFillSmallTableTime = MeasureExecutionTimeMethod(sconn, SmallTableToFill, ExecuteDataAdapterFillStep);
readerLoadSmallTableTime = MeasureExecutionTimeMethod(sconn, SmallTableToFill, ExecuteSqlReaderLoadStep);
// tiny data set measurements
AdapterFillTinyTableTime = MeasureExecutionTimeMethod(sconn, TinyTableToFill, ExecuteDataAdapterFillStep);
readerLoadTinyTableTime = MeasureExecutionTimeMethod(sconn, TinyTableToFill, ExecuteSqlReaderLoadStep);
}
using (StreamWriter writer = new StreamWriter("result_sql_compare.txt"))
{
writer.WriteLine("10000 rows");
writer.WriteLine("Sql Data Adapter 100 times table fill speed 10000 rows: {0} milliseconds", AdapterFillLargeTableTime);
writer.WriteLine("Sql Data Reader 100 times table load speed 10000 rows: {0} milliseconds", readerLoadLargeTableTime);
writer.WriteLine("1000 rows");
writer.WriteLine("Sql Data Adapter 100 times table fill speed 1000 rows: {0} milliseconds", AdapterFillMediumTableTime);
writer.WriteLine("Sql Data Reader 100 times table load speed 1000 rows: {0} milliseconds", readerLoadMediumTableTime);
writer.WriteLine("100 rows");
writer.WriteLine("Sql Data Adapter 100 times table fill speed 100 rows: {0} milliseconds", AdapterFillSmallTableTime);
writer.WriteLine("Sql Data Reader 100 times table load speed 100 rows: {0} milliseconds", readerLoadSmallTableTime);
writer.WriteLine("10 rows");
writer.WriteLine("Sql Data Adapter 100 times table fill speed 10 rows: {0} milliseconds", AdapterFillTinyTableTime);
writer.WriteLine("Sql Data Reader 100 times table load speed 10 rows: {0} milliseconds", readerLoadTinyTableTime);
}
Process.Start("result_sql_compare.txt");
}
private long MeasureExecutionTimeMethod(SqlConnection conn, string query, Action<SqlConnection, string> Method)
{
long time; // know C#
// execute single read step outside measurement time, to warm up cache or whatever
Method(conn, query);
// start timing
time = Environment.TickCount;
for (int i = 0; i < 100; i++)
{
Method(conn, query);
}
// return time in milliseconds
return Environment.TickCount - time;
}
private void ExecuteDataAdapterFillStep(SqlConnection conn, string query)
{
DataTable tab = new DataTable();
conn.Open();
using (SqlDataAdapter comm = new SqlDataAdapter(query, conn))
{
// Adapter fill table function
comm.Fill(tab);
}
conn.Close();
}
private void ExecuteSqlReaderLoadStep(SqlConnection conn, string query)
{
DataTable tab = new DataTable();
conn.Open();
using (SqlCommand comm = new SqlCommand(query, conn))
{
using (SqlDataReader reader = comm.ExecuteReader())
{
// IDataReader Load function
tab.Load(reader);
}
}
conn.Close();
}
Wyniki:
10000 rows:
Sql Data Adapter 100 times table fill speed 10000 rows: 11782 milliseconds
Sql Data Reader 100 times table load speed 10000 rows: 26047 milliseconds
1000 rows:
Sql Data Adapter 100 times table fill speed 1000 rows: 984 milliseconds
Sql Data Reader 100 times table load speed 1000 rows: 2031 milliseconds
100 rows:
Sql Data Adapter 100 times table fill speed 100 rows: 125 milliseconds
Sql Data Reader 100 times table load speed 100 rows: 235 milliseconds
10 rows:
Sql Data Adapter 100 times table fill speed 10 rows: 32 milliseconds
Sql Data Reader 100 times table load speed 10 rows: 93 milliseconds
W przypadku problemów z wydajnością użycie metody SqlDataAdapter.Fill jest znacznie bardziej wydajne. Więc jeśli nie chcesz strzelić sobie w stopę, użyj tego. Działa szybciej w przypadku małych i dużych zestawów danych.