Datareader è più veloce del set di dati quando si compila un datatable?

Quale sarebbe più veloce.

1) Ciclo di un datareader e creazione di un datatable popolato basato su righe e colonne personalizzate

2) O creando un object DataAdapter e semplicemente (.Fill) un datatable.

Le prestazioni di un datareader sono ancora valide quando si crea dynamicmente un datatable?

DataAdapter utilizza un DataReader sotto il cofano, quindi la tua esperienza sarebbe probabilmente la stessa.

Il vantaggio di DataAdapter è il taglio di un sacco di codice che avrebbe bisogno di manutenzione.

Questo dibattito è un po ‘un problema religioso quindi guardati intorno e decidi che cosa funziona meglio per la tua situazione:

Supponendo che in realtà si desidera che tutti i dati tornino dal database, il tempo impiegato nel database e nella rete è quasi certo di sminuire il tempo impiegato nel processo per popolare strutture di dati in memoria.

Sì, in alcuni casi si potrebbe ottenere un piccolo risparmio utilizzando DataReader – e in particolare se si desidera eseguire il stream dei dati potrebbe essere utile – ma se effettivamente ne hai bisogno tutto, rimango con il codice più semplice. Se si ritiene che la popolazione di DataSet stia causando un notevole problema di prestazioni, configurarla e quindi provare a migliorarla.

La tua opzione n. 1 sarebbe più lenta. Tuttavia, c’è un modo migliore per convertire un datareader in un datatable che aggiungere righe personalizzate a mano:

DataTable dt = new DataTable(); using (SqlConnection conn = GetOpenSqlConnection()) using (SqlCommand cmd = new SqlCommand("SQL Query here", conn) using (IDataReader rdr = cmd.ExecuteReader()) { dt.Load(rdr); } 

Non posso commentare la differenza tra questo e l’utilizzo di .Fill() .

Non posso parlare di riempire un datatable in sé, ma usare un datareader è il metodo di lettura più efficiente.

Il datareader è più veloce. E se usi 2.0+, probabilmente non devi nemmeno usare un datatable. Puoi usare un elenco generico del tuo object.

È bello avere DataReader quando è necessario, ad esempio, mostrare lo stato di avanzamento del caricamento dei dati. In DataSet non puoi fare qualcosa nel mezzo del caricamento dei dati.

D’altra parte DataSet è un object all-in-one. Quindi DataSet è molto più lento. DataReader può darti ulteriore spinta nei posti del tuo codice in cui il funzionamento dei dati è molto lento. In questi luoghi, cambia da DataSet a DataReader. DataReader richiede anche meno spazio in memoria.

Certo, ci vuole più tempo per codificare un buon DataReader, ma ne vale la pena. Ad esempio quando giochi con immagini o musica prese dal database.

Maggiori informazioni su questo argomento in MSDN Magazine

Come con molte domande come questa la risposta è: dipende.

Se non si conosce la struttura dei dati in primo piano e si stanno creando TableAdapters al volo, la DataTable dynamic sarebbe più efficiente. C’è una buona dose di generazione del codice coinvolta nella creazione di un TableAdapter.

Tuttavia, se si conosce la struttura dei dati in primo piano, la domanda diventa: Quanta funzionalità ho bisogno?

Se hai bisogno di un’implementazione CRUD completa, ci sono alcune efficienze ottenute usando un TableAdapter invece di scrivere tutto quel codice CRUD tu stesso. Inoltre, l’implementazione di TableAdapter è OK (non eccezionale). Se hai bisogno di qualcosa di più efficiente, allora potresti stare meglio usando nHibernate o qualche altro ORM.

Se non hai bisogno di un’implementazione CRUD completa (ovvero, questa è una soluzione di sola lettura) e conosci la struttura dei dati in anticipo, dovrai testare l’efficienza di un’implementazione di sola lettura di TableAdapter su un DataTable generato dynamicmente . Se fossi un uomo scommettente, metterei i miei soldi sull’implementazione di TableAdapter dato che leghi i dati una volta sola e li leggo più volte.

Passando da DataReader ‘s Read che è un approccio forward-only, ad una sola fila alla volta, che legge i dati in modo sequenziale in modo da ottenere i record non appena vengono letti durante la connessione, sarà il migliore per la memoria e prestazione.

Detto questo, tra i due approcci, trovo IDataAdapter.Fill molto più veloce di DataTable.Load . Ovviamente ciò dipende dalle implementazioni. Ecco un punto di riferimento tra i due che ho postato qui :

 public DataTable Read1(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(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]; } } } } 

Il secondo approccio ha sempre sovraperformato il primo.

 Stopwatch sw = Stopwatch.StartNew(); DataTable dt = null; for (int i = 0; i < 100; i++) { dt = Read1(query); // ~9800ms dt = Read2(query); // ~2300ms dt = Read1(query); // ~4000ms dt = Read2(query); // ~2000ms dt = Read1(query); // ~5700ms dt = Read2(query); // ~5700ms dt = Read1(query); // ~850ms dt = Read2(query); // ~600ms dt = Read1(query); // ~3900ms dt = Read2(query); // ~3700ms } sw.Stop(); MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString()); 

Read1 aspetto migliore sugli occhi, ma l’adattatore dati funziona meglio (per non confondere che un db ha sovraperformato l’altro, le query erano tutte diverse). Tuttavia, la differenza tra i due dipendeva dalla query. Il motivo potrebbe essere che Load richiede diversi vincoli da controllare riga per riga dalla documentazione quando si aggiungono le righe (è un metodo su DataTable ) mentre Fill è su DataAdapters che sono stati progettati proprio per questo: la creazione rapida di DataTables.