ThinkMobile.it
Comunità Italiana sullo sviluppo Mobile in ambiente Microsoft

SQLCE/2005 Performance: DataReader, DataSet e Update

rated by 0 users
This post has 0 Replies | 0 Followers

Top 10 Contributor
Posts 1,389
Roberto Brunetti Posted: 10-06-2005 15:30

Ho messo nel blog questo mini.-articolo sulle performance di DataReader e DataSet. Lo ripropongo in questo forum.

Facendo qualche prova con SQL 2005 Mobile ormai giunto alla versione RC, si confermano, era ovvio, i dati sulle performance del DataReader rispetto all'utilizzo del DataSet. Riprendo l'argomento visto che proprio oggi mi è arrivata una domanda su questo argomento. Provo a mettere tutto sul piatto.

Il DataReader è il meccanismo più veloce e più leggero per leggere i dati da un db SQLCE/Sql 2005 Mobile (è vero anche per SQL Server). E' più veloce perchè utilizza un cursore forward-only, read-only sui dati; il DataAdapter che si utilizza per riempire un DataSet/DataTable internamente al metodo Fill utilizza un DataReader per scorrere i dati e popolare la DataTable; prima di effettuare le lettera esegue una serie di operazioni (visibili facilmente usando Anakrino o Reflector). E' più leggero in quanto il DataSet fa double buffering dei dati: vuol dire che prima scorre tutti i record per riempire la DataTable e poi un secondo giro sulle DataRow per popolare il controllo in binding. Su dati di una certa importanza (vuol dire già 10 Mb su un dispositivo Windows CE) si arriva ad un rapporto di quasi 5 a 1.

Detto questo il DataReader non è bindable verso i controlli delle Windows Form CE: questo vuol dire dover scrivere un po' di codice per popolare i controlli: come sempre, più ci si sbatte, meglio va il prodotto !. Inoltre il DataReader non passa via Web Service e non è serializzabile in MSMQ: il DataReader non contiene dati, è semplicemente il lettore dei dati, quindi non può essere serializzato o salvato su disco per capirci. Quando si utilizza un reader occorre prevedere gli statement di Update, Insert e Delete a mano in quanto non abbiamo nessun DataAdapter a darci una mano...ma a farci perdere tempo prezioso su ambienti con numerose restrizioni rispetto a un PC. Voglio dire che un DataSet a volte è una scelta obbligata per utilizzare DataSet (N.B. nella 2.0 del CompactFramework esiste la serializzazione quindi si possono usare classi custom sia per l'invio/ricezione di dati tramite Web Service sia verso MSMQ).

Anche il DataReader può essere velocizzato durante la sua lettura usando i vari metodi "typed" per accedere ai campi. Anziche scrivere dr["Nome"] conviene usare dr.GetString(x) dove x è la posizione del campo. Usare campi posizionali non è sicuramente il massimo: 1) dobbiamo ricordarceli, 2) se cambiano qualcosa nella query non quadrano più. Il DataReader espone però il metodo GetOrdinal che restituisce l'indice di un campo in base al nome. E' chiaro che fare questo:

while(!dr.Read())
{
   listbox.AddItem(dr.GetString(dr.GetOrdinal("Nome")));
}

non ha molto senso in quanto per ogni record e ogni campo viene prima ricercata la posizione e poi restituita la stringa.

Di solito quindi si usa questa tecnica: prima di iniziare il ciclo while si memorizzano le posizioni e poi si cicla sui dati

int posNome = dr.GetOrdinal("Nome");
while(!dr.Read())
{
   listbox.AddItem(dr.GetString(posNome));
}

Facendo questo si legge la posizione una sola volta e poi usiamo i metodi typed per accedere ai campi per ogni record: il meglio per performance e il meglio per elasticità.
 
Facendo gli update, insert e delete convien usare query parametriche. Ecco un esempio:
 
cmd.CommandText = “UPDATE myTable set col1=? where col2=?";
cmd.Parameters.Add("p1", SqlDbType.xxx);
cmd.Parameters.Add("p2", SqlDbType.xxx);
cmd.Prepare(); // se la query è eseguita più volte utilizzare prepare
cmd.Parameters["p1"].Value = xxxx;
cmd.Parameters["p2"].Value = xxxx;
                   
cmd.ExecuteNonQuery();
 
Le query parametriche hanno un tempo di risposta notevolmente migliore in quanto l'execution plan per eseguire la query può essere riutilizzato senza doverlo ricalcolare a ogni esecuzione.
In SQLCE 2.0 i parametri sono posizionali, mentre SQL 2005 Mobile introduce i named parameter.
 
Con SQL 2005 Mobile, la libreria SqlClient si arricchisce anche di un'altra classe SqlCeResultSet: è un cursore sui dati che come performance si avvicina al DataReader, ma ha le stesse caratteristiche di aggiornabilità, scrolling e binding di un DataSet/DataTable.
 
Ne parliamo in un prossimo post.
Page 1 of 1 (1 items) | RSS
Powered by Community Server (Non-Commercial Edition), by Telligent Systems