Direi che una buona pagina da cui partire è questo documento su MSDN :Performance Considerations for Entity Framework Applications, che punta ad una serie di risorse che ho trovato interessanti.
Beh, forse è la prima domanda che ci si pone. Cosa succede al momento della creazione dell’ObjectContext, il punto di accesso con cui usiamo EF ? In un bel post del team viene evidenziato il dettaglio delle operazioni fatte ed il relativo costo:
Da una rapida occhiata si vede come tra le operazioni che hanno più costo, in particolare allo start-up, ci sono:
Nell’ 1% c’è il tempo di esecuzione vero e proprio della query. Nello stesso post c’è anche il grafico del dettaglio di questo costo, con la spiegazione delle singole voci, tolto il tempo di start-up quindi. Vi riporto qui per comodità di lettura:
Ci potremmo chiedere. Ogni volta che creo un ObjectContext, per i tempi di start-up? O quando eseguo una query ?
Nella documentazione MSDN vediamo che alcuni di questi costi sono legati (quindi in qualche modo vivono in una cache) all’ Application Domain e non alla creazione della singola istanza di ObjectContext. Guardate la tabella seguente:
Nell’immagine vedete che i costi più alti ci sono una sola volta per ogni Application Domain.
Infatti se in una Console Application eseguite una query con due istanze dello stesso object Context, che esegue la tessa query 4 volte con il primo e altre 4 volte con il secondo, vedete il costo molto alto solo nel primissimo run:
Inoltre come detto, potrei ridurre il costo della fase di generazione delle view, come documentato qui, nel caso il mio application domain venisse creato e distrutto più volte.
Sempre dalla tabella vista in precedenza, si vedono i costi del tempo di preparazione ed esecuzione delle query sono distinti. EF fa in modo che il tempo di preparazione di ogni singola query sia speso una sola volta per query e quindi poi parte del lavoro riutilizzato. Ad ogni modo è abbastanza intuitivo pensare che all’aumentare della complessità della query i tempi di preparazione ed esecuzione aumenteranno inevitabilmente.
Per ottimizzare il tempo complessivo speso per una query è possibile utilizzare delle query compilate (Documentazione MSDN qui). Una query compilata viene creata una volta sola e puoi può essere riutilizzata con diversi parametri.
Trovate un esempio d’utilizzo in questo post del team di prodotto.
Un altro aspetto che nella tabella sopra è contraddistinto come low, ma che è proporzionale al numero di oggetti ritornati e quello relativo al tracking, questa funzionalità dell’ ObjectStateManager che tiene traccia della “vita” delle nostre entità: aggiunta, cancellazione, modifica e l’Entity Key viene usata per identificare le istanze degli stessi.
Quando usate come mergeoptions NoTracking, le operazioni di aggiornamento e risoluzione dell’identità della cache dell’ObjectStateManager non vengono eseguite. Questa opzione ha senso se non dobbiamo tracciare operazioni di modifica/cancellazione e inserimento dei nostri oggetti, ne è tipico l’uso in applicazioni ASP.NET in cui si fa il recupero di dati e non si è interessati ad altro.
Da quanto visto in precedenza appare anche un altro aspetto che può essere utile investigare : all’aumentare del numero di tabelle del db che fanno parte di uno stesso Entity Data Model (EDM) le performance decrescono. Da questi due post del team (primo e secondo) i suggerimenti sono di pensare di dividere l’EDM in più parti quando il numero di tabelle è elevato, quando cioè si raggiungono le 50-100 tabelle.
La divisione dell EDM in parti con il riutilizzo parziale di tipi tra EDM diversi non è una cosa banale, poichè il designer di Visual Studio non c’aiuta e quindi bisogna operare a mano sul file CSDL. Trovate degli esempi con diverse strategie proprio nei due post che vi segnalo.
L’ottimizzazione delle performance di EF può tenere conto di diversi aspetti, che ho cercato di ricollegare con un po’ di documentazione, direi che può essere utile almeno tenere presente di:
PingBack from http://www.anith.com/?p=27441
Dopo aver seguito le istruzioni per ottimizzare il primo avvio di EDM ( http://msdn.microsoft.com/en-us/library/bb896240.aspx)
ho rifatto i test di performances ma senza ottenere risultati:
Il mio EDM è composto da circa 20 tabelle relazionate tra loro e il problema che riscontro è che la prima chiamata ( query ) impiega 1 minuto ad essere eseguita. Le successive circa 380 ms.
Ho inserito le operazioni di prebuild, generato e aggiunto il file .cs e anche i files .msl .ssdl e .csdl
Modificato la stringa di connessione e rieseguito il test ma nulla è cambiato.
Avete qualche suggerimento??