В соответствии с DataReader
Read
, который является подходом «только вперед», по одной строке за раз, который читает данные последовательно, так что вы получаете записи, как только они читаются при подключении, будет лучше для памяти и производительности.
Тем не менее, между двумя подходами я нахожу IDataAdapter.Fill
намного быстрее, чем DataTable.Load
. Конечно, это зависит от реализаций. Вот эталон между двумя, которые я выложил здесь :
public DataTable Read1<T>(string query) where T : IDbConnection, new()
{
using (var conn = new T())
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.ConnectionString = _connectionString;
cmd.Connection.Open();
var table = new DataTable();
table.Load(cmd.ExecuteReader());
return table;
}
}
}
public DataTable Read2<S, T>(string query) where S : IDbConnection, new()
where T : IDbDataAdapter, IDisposable, new()
{
using (var conn = new S())
{
using (var da = new T())
{
using (da.SelectCommand = conn.CreateCommand())
{
da.SelectCommand.CommandText = query;
da.SelectCommand.Connection.ConnectionString = _connectionString;
DataSet ds = new DataSet(); //conn is opened by dataadapter
da.Fill(ds);
return ds.Tables[0];
}
}
}
}
Второй подход всегда превосходил первый.
Stopwatch sw = Stopwatch.StartNew();
DataTable dt = null;
for (int i = 0; i < 100; i++)
{
dt = Read1<MySqlConnection>(query); // ~9800ms
dt = Read2<MySqlConnection, MySqlDataAdapter>(query); // ~2300ms
dt = Read1<SQLiteConnection>(query); // ~4000ms
dt = Read2<SQLiteConnection, SQLiteDataAdapter>(query); // ~2000ms
dt = Read1<SqlCeConnection>(query); // ~5700ms
dt = Read2<SqlCeConnection, SqlCeDataAdapter>(query); // ~5700ms
dt = Read1<SqlConnection>(query); // ~850ms
dt = Read2<SqlConnection, SqlDataAdapter>(query); // ~600ms
dt = Read1<VistaDBConnection>(query); // ~3900ms
dt = Read2<VistaDBConnection, VistaDBDataAdapter>(query); // ~3700ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
Read1
выглядит лучше на глазах, но адаптер данных работает лучше (не путать, что один дб превзошел другой, все запросы были разными). Разница между ними зависит от запроса. Причиной может быть то, что Load
требует, чтобы различные строки проверялись строка за строкой из документации при добавлении строк (это метод на DataTable
), в то время как Fill
на DataAdapters, которые были разработаны только для что - быстрое создание DataTables.