Ciao a tutti

 

Tratto dal mio libro Learning .NET High Performance Programming,
di seguito espongo uno degli errori comuni più limitanti dell’esperienza d’uso di EF

EF è un sistema che rende più facile l’uso del DB (ad oggetti ovviamente)
Va però tenuto conto che anche se in media chi ha scritto EF sia cento volte più bravo del programmatore generico a creare SQL (anche questo generato ad oggetti con gli expression tree… non mi dilungo), ci sono degli usi frequenti che in realtà sono dei limiti e non degli acceleratori di performance

Mi riferisco principalmente al fatto di scrivere in LINQ query che poi (come sappiamo) vanno a diventare SQL grazie ai data provider di EF.

Immaginiamo di scrivere una query per calcolare ad esempio i totali di una lista di fatture

Normalmente scriviamo una LINQ con dentro il calcolo del totale usando la navigation property verso gli elementi. Questo è molto efficiente perchè senza generare oggetti inutili ci facciamo tornare il totale dal DB

Adesso una domanda filosofica: è giusto che la CPU del DB sia usata per un calcolo di business?!?!?!?!

Torniamo alla realtà: immaginiamo di avere 10.000 utenti e 10 web server… se facciamo sempre la stessa query, stiamo scalando davvero sui 10 server?
Ovviamente NO. Perchè è sempre il DB a calcolare il totale

Questo è quel comportamento nascosto che normalmente sembra una soluzione che ottimizza le performance, ma in realtà limita altre performance in modo drastico

La soluzione è usare un oggetto anonimo per leggere una query di Fattura e di ElementiFattura, anche questi in una seconda lista di oggetti anonimi con soli i dati necessari al caso (dettaglio base + valori per il calcolo). Così facendo si leggono pochi dati dal DB (ricordo che un DB è ufficialmente un sistema di persistenza quindi basta pippe sul fatto che lo “sfruttiamo” per leggere/scrivere dati) e si fa il calcolo in LINQ (magari dopo un .ToArray()/.ToList()) sul web-server

Con questa soluzione, nel caso empirico di un test su un DB semi-vuoto avremo ancora buone performance, mentre su un test reale con migliaia di utenti e svariati server scalati in orizzontale, avremo davvero la scalabilità

Ultimo dettaglio: anche la velocità del DB di I/O è limitata, ma molto meno della sua potenza di calcolo, e comunque possiamo poi scalare i DB in orizzontale spalmando i dati su più server raggruppati per Tenant o per altro

 

a presto