Ho un problema di prestazioni con alcuni metodi nel mio livello di servizio. I metodi che mi causano problemi hanno una certa logica, ma è la connessione db che richiede più del 95% di tempo di esecuzione. Il problema è sfortunatamente hardware, la macchina è solo lenta. Ma lasciatemi spiegare prima il problema del software:
Lo scenario è come questo (semplificato):
La società vende automobili, c'è un'entità Car
e un'entità PurchaseOrder
. Nell'applicazione, c'è una visualizzazione Car
con tutto PurchaseOrders
. C'è una funzione per determinare PurchaseOrdersStatus
. Non sarebbe lento, ma deve interrogare il database "lento" alcune volte. Le query sono molto semplici, come:
"Verifica se FooId
esiste nella tabella bar
".
Se l'auto ha pochi ordini di acquisto, la query è veloce. Ma quando la macchina ha centinaia di ordini, sta diventando molto lento. Perché questa query deve essere eseguita molte volte. Ho trovato la soluzione:
- Esamina tutti
FooId
s dalla tabellabar
- Salva questo elenco di ID nella memoria
- In quelle centinaia di chiamate sto verificando se l'id esiste nella memoria, il che rende il modo più veloce.
La mia domanda è, c'è uno schema di "prequering" dei dati dal database, mettendolo in memoria?
Nelle mie classi di persistenza dei dati, come CarData
, ho letteralmente il metodo "Inizializzazione" e gli elenchi dei membri con ID. Ma non sono sicuro se questo è il modo giusto per farlo.
Modifica
Sto facendo una grande query nel database veloce, è molto veloce anche per molti record. Per ottenere "lo stato" ho bisogno di fare qualche altra query, che sono in tabelle totalmente non collegate tra loro, alcune delle quali sono in db molto lento (btw. L'architettura db è davvero terribile, ma è un db legacy, quindi tutto ciò che posso fare è lamentarmi). È possibile eseguire una query tra database (costituita da sottoquery, ad esempio ... WHERE carId IN (select cardId from ...
- ma è molto lenta.
EDIT2: la mia soluzione proposta
Nel mio progetto ho alcune classi FooData
, alcune hanno la corrispondente FooCache
class. La cache ha un aspetto simile a Data, ha DataContext, Collections (elenco di id memorizzato nella cache o qualsiasi altra cosa ho bisogno) e un metodo Initialize
. Inserisco FooCache
in FooData
tramite IoC (quindi ogni volta che viene creato FooData
), MA non lo inizializzo. Solo nei metodi in cui ho bisogno del caching, chiamo FooCache.Initialize();
all'inizio. FooData
prima di andare al database, controlla se FooCache è inizializzato. Se non lo è, va al db.