Come EF 8 ha ottimizzato le query che usano il metodo Contains

di Stefano Mostarda, in .NET Framework, LINQ,

Uno dei task più ricorrenti quando si lavora con un Entity Framework è quello di dover recuperare una serie di entity a partire da una lista di id. Questo in LINQ si traduce nell'avere una variabile con la lista di id che all'interno del metodo Where viene usata insieme a Contains.

int[] ids = [1,2,3,4,5]
var people = await ctx.People
  .Where(c => ids.Contains(c.Id))
  .ToListAsync()

Sebbene questo codice sia perfettamente funzionante, la sua traduzione in SQL non è stata ottimale fino alla versione 7. Infatti fino a quella versione il codice veniva tradotto nel sequente codice SQL (semplificato).

SELECT * 
FROM People
WHERE Id IN (1,2,3,4,5)

Come possiamo vedere, la lista di id è stampata nel codice SQL generato e quindi ogni volta che cambiano gli id, SQL Server genera un nuovo query plan e lo mette in cache causando potenziali problemi di performance perchè altre query vengono eliminate dalla cache.
Con la versione 8, per ovviare a questo problema, il team ha sfruttato le potenzialità di JSON e ha modificato il codice SQL generato nel seguente.

SELECT *
FROM People
WHERE Id IN (
    SELECT value
    FROM OPENJSON(@__ids_0) WITH ([value] int '$')
)

Come si vede, la clausola IN non contiene più la lista di valori da cercare. Questa è viene tradotta in JSON e caricata in una tabella in memoria tramite la funzione OPENJSON. Grazie a questa nuova traduzione, il codice SQL rimane sempre lo stesso a prescindere dagli id usati e così ottimizza le performance deldatabase.

Questo script mostra il codice SQL generato per Sql Server. Tuttavia, questa modifica è stata fatta prima a livello core di EF, e poi a livello di provider per SQL. Questo significa che chi crea i provider per altri database, può sfruttare le modifiche al core per generare un SQL ottimizzato per lo specifico database.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi