Pasando por DataReader
Read
que es un acercamiento solo de reenvío, de una fila a la vez, que lee datos secuencialmente para que pueda obtener registros tan pronto como se leen al conectarse, será el lo mejor para la memoria y el rendimiento.
Dicho esto, entre los dos enfoques, encuentro IDataAdapter.Fill
mucho más rápido que DataTable.Load
. Por supuesto que depende de las implementaciones .. Aquí es un punto de referencia entre los dos que he publicado here:
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];
}
}
}
}
El segundo enfoque siempre superaron a la primera.
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
se ve mejor en los ojos, pero adaptador de datos funciona mejor (no confundir que uno db superó a la otra, las consultas eran todas diferentes). La diferencia entre los dos dependía de la consulta sin embargo. La razón podría ser que Load
requiere que se verifiquen varias restricciones fila por fila from the documentation al agregar filas (es un método en DataTable
), mientras que Fill
está en DataAdapters que fueron diseñados solo para eso: creación rápida de DataTables.
Ver mi publicación: eso es menos código que usar un DataAdapter. –