Ho un codebase EF Core in codice in esecuzione su SqlLite con una entità con circa 20 colonne e 10 righe. Una pagina richiede questa entità in codice come questo:
var start = DateTime.Now;
var entA = await _context.entA.FromSql("SELECT * FROM entA "+
"where (Name like '%_Demo' or EXISTS(SELECT NULL FROM entB WHERE StudyId = entA.ID and email = @email)) AND IsDeleted = 0 "+
"order by colC COLLATE NOCASE",
new SqliteParameter("@email", User.Identity.Name))
.ToListAsync();
log.Info($"User {User.Identity.Name} requested entA, in {DateTime.Now.Subtract(start).TotalMilliseconds}");
Ho attivato la registrazione di EF Core e vedo la query con
Executed DbCommand (2ms) [Parameters=[@email='?'], CommandType='Text', CommandTimeout='30']
Tuttavia nei log (anche dopo averlo eseguito più volte) vedo
2018-06-28 15:16:49,442 INFO Controller - User user@domain.com requested entA, in 166,0095
Cosa sta succedendo per i ~ 160 ms che non vengono utilizzati per eseguire la query?
Aggiornamento: Come suggerito da Xanatos ho rimosso l'attesa e asincrono e fortunatamente sto vedendo più o meno gli stessi numeri
INFO Controller - User user@domain.com requested entA, in 207,0118
INFO Controller - User user@domain.com requested entA, in 164,0094
INFO Controller - User user@domain.com requested entA, in 225,0129
INFO Controller - User user@domain.com requested entA, in 180,0103
Sarebbe piuttosto triste se .net stava aspettando 100ms prima di restituire i risultati di un compito
EDIT: ho scoperto che il passaggio da un account all'altro accelera notevolmente le cose per le query di sola lettura:
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
Stai usando await
. Non vi è alcuna garanzia che nell'attimo in cui i dati siano "pronti" l' await
continui. Se si vuole fare una misurazione, rimuovere await
e cambiare ToListAsync()
in ToList()
. Quindi possiamo parlare di benchmark.