Ho una piccola domanda sulle prestazioni con Entity Framework.Entity Framework - Prestazioni nel conteggio
Qualcosa di simile
using (MyContext context = new MyContext())
{
Document DocObject = context.Document.Find(_id);
int GroupCount = context.Document.Where(w=>w.Group == DocObject.Group).ToList().Count();
}
dura circa 2 secondi nel mio database (circa 30k set di dati), mentre questo
using (MyContext context = new MyContext())
{
Document DocObject = context.Document.Find(_id);
int GroupCount = context.Document.Where(w=>w.Group == DocObject.Group).Count();
}
richiede 0,02 secondi.
Quando il mio filtro per 10 documenti aveva 20 secondi di attesa, ho controllato il mio codice e l'ho modificato per non utilizzare ToList()
prima dello Count()
.
Qualche idea del motivo per cui è necessaria questa linea per 2 secondi con lo ToList()
?
Questa risposta non è corretta. Il problema non ha nulla a che vedere con * caricamento pigro * o esecuzione differita; entrambe le query saranno eseguite "con entusiasmo": la prima è dovuta a 'ToList()', la seconda a 'Count()'. La * differenza * è che la seconda query è * ottimizzata * per una query 'SELECT COUNT (*)' che è molto più veloce. – InBetween
Questa è semantica. Non ho mai affermato che Count() non eseguisse avidamente, ma l'oggetto restituito dal metodo Where sarà del tipo IQuerable che è un oggetto proxy mentre ToList() eseguirà una selezione completa e caricherà avidamente l'intero oggetto. Count() viene eseguito in entrambi gli esempi, nel secondo viene eseguito su IQueryable e nel primo viene eseguito nell'elenco valutato . Il motivo della perdita di prestazioni è sicuramente dovuto all'esecuzione di un intero SELECT e non SELECT COUNT (*) che in questo caso è il risultato del caricamento avido degli oggetti utilizzando ToList. –
Marcus
Non voglio entrare in una discussione su questo. La verità è che la seconda soluzione è * più veloce * perché l'EF ottimizza la query 'DB' su una query' SELECT COUNT (*) ', un fatto che non si indica da nessuna parte nella risposta. Riesci semplicemente a caricare pigro, a interrompere l'esecuzione e ora "IQuerable" che non ha nulla a che fare con il problema. Nella seconda opzione 'Count()' * esegue anche impazientemente * la query e carica "l'oggetto (i)". La differenza è che la query è stata ottimizzata a livello di query e pertanto restituisce un singolo valore. –
InBetween