Interrogare dal database in un ciclo una cattiva pratica? [duplicare]

4

In primo luogo, sto ancora imparando a fare le cose nelle migliori pratiche possibili. Mi piacerebbe sapere quale sarebbe una buona pratica quando si tratta di query di database. Ho visto codici che interrogano all'interno del ciclo per verificare se tali dati esistono o meno. Quindi diciamo che ho una serie di codici mostrati di seguito.

// assume that institutions are the list of institutionids
foreach(var institution in institutions)
{
    // get here the project for an institution.
    var projects = _projectRepository.GetForInstutition(institution);

    // do sets of commands here...
}

Perché sarebbe meglio fare la query per tutti i dati necessari dal database prima di fare qualcosa sui dati? Mi piacerebbe avere una migliore comprensione su questo.

    
posta rpmansion 17.03.2018 - 17:29
fonte

2 risposte

3

Questo è un caso della gerarchia di memoria che stabilisce il modo più efficiente di fare le cose.

I computer di solito hanno diversi tipi di archiviazione; i più grandi sono anche quelli più lenti. I registri CPU sono i più veloci di tutti ma anche i più piccoli; la cache on-chip è più grande ma più lenta, le cache di secondo livello sono ancora più grandi, la RAM è ancora più grande, la memoria di massa (come i dischi rigidi) è ancora più grande, i dispositivi di rete hanno dimensioni praticamente illimitate.

Di solito, la differenza nella velocità di accesso è drammatica. Un database può variare tra l'essere simile a un disco rigido e l'essere simile a un accesso di rete, ma è quasi sempre molto più lento dello spostamento dei dati da e verso la RAM. In genere, anche l'apertura di una connessione e l'invio di una query richiede così tanto tempo che potresti aver eseguito miliardi di operazioni in memoria nello stesso momento.

Pertanto, finché tutti i risultati sono attesi per entrare nella RAM, di solito è meglio eseguire una una query di database per ottenere tutti i dati necessari e quindi iniziare a operare su di essi piuttosto che interrogare, elaborare , esegui nuovamente una query, elabora di nuovo, ecc. Riduce drasticamente il tempo complessivo necessario per completare il ciclo.

    
risposta data 17.03.2018 - 17:51
fonte
1

Questo è il classico compromesso spazio-tempo

Certo, potresti inserire tutto nella memoria del tuo computer in questo modo:

var projectMap = _projectRepository.GetForInstutitions(institutions);
foreach(var institution in institutions)
{
    var projects = projectMap.get(institution);

    // do sets of commands here...

}

Io chiamo questo slurping . Hai già pubblicato l'alternativa: chuncking . Slurping ridurrà il numero di richieste al database su chunking. Ma che cosa fa alla memoria del tuo computer? Beh, dipende da quanto grande e quanto stai risucchiando nella memoria. Entra in funzione abbastanza e all'improvviso stai sbattendo il disco rigido mentre il SO scambia la memoria con il file di paging a causa di errori di cache.

Devi testare cose del genere per vedere se è davvero un problema. Puoi sbagliare ad entrambi gli estremi. La chiave è trovare un equilibrio.

    
risposta data 17.03.2018 - 18:00
fonte

Leggi altre domande sui tag