dichiarazione del problema: come parallelizzare inserti in SQL Server (2008)parallelizzazione massiccia inserti in SQL Server da C# (per migliorare le prestazioni di tempo)
sto eseguendo massiccia calcolo numerico per la ricerca scientifica in C# lavoratori multithread che fondamentalmente fai una cosa: prova migliaia di possibili configurazioni (combinazioni di matrici) per un periodo di tempo (in giorni) e memorizza i risultati in un database di SQL Server.
Se memorizzo i risultati uno a uno in DB (~ 300.000 righe per sessione di calcolo * 100 di sessioni), uno dopo l'altro, finisco per attendere ore per il termine del processo di archiviazione.
La progettazione del database è molto semplice:
- Combinazione Imposta
CS_ID1, Valore A1, Valore B1, Valore C1
CS_ID2, Valore A2, Valore B2, Valore C2
. ... - Risultati per giorno
CS_ID1, Giorno1 Risultato 1
CS_ID1, Giorno 2, 2 Risultato
CS_ID1, 3 ° giorno, Risultato 3
.........
.........
CS_ID2, Giorno1 Risultato N
CS_ID2, Giorno 2, Risultato N + 1
CS_ID2, 3 ° giorno, Risultato N + 2
Eac h "Combination Set" viene testato in base ai giorni campione e i suoi risultati giornalieri vengono elaborati in un singolo thread C#, dove viene generata una query LINQ/SQL e inviata a DB appena prima della fine del thread. Tranne le sequenze degli ID dell'insieme di combinazioni, non esiste alcuna relazione logica tra i risultati. Questo è molto importante: Questo è il motivo per cui ho pensato di parallelizzare la roba inserto come fondamentalmente equivale ad un bulk dump di blocchi risultato
Un altro dettaglio che potrebbe essere importante è che è possibile determinare in anticipo quanto molte righe verranno inserite nel Database (per blocco e in totale). Questo probabilmente potrebbe aiutare a organizzare gli spazi dei tavoli, dividerli attraverso le pagine, prefissare intervalli di ID per memorizzare blocchi contemporaneamente, o qualcosa del genere (No, non sono "alto" o qualcosa del genere :-))
Accolgo con favore qualsiasi tipo di suggerimento al fine di rendere questo inserimento il più breve possibile.
Si prega di prendere in considerazione che io sono uno sviluppatore C#, con una conoscenza di base di SQL Server e non molto familiare con i concetti DBA tecnici profondi (ho visto che le modifiche di blocco sono MOLTO numerose, che ci sono anche funzionalità multithreaded e asincrone, ma devo ammettere che mi sono perso solo nella foresta :-))
ho 12 core CPU disponibili, e 24Go RAM
EDIT: Tie-break
Accolgo con favore qualsiasi suggerimento intelligente sul tempo di monitoraggio per l'intero processo: dai thread C# dall'inizio/fine ai report dettagliati sull'inserto del server SQl (cosa succede quando, come e dove).
Ho provato a loggare con NLog ma distorce drasticamente il tempo di elaborazione, quindi sono alla ricerca di soluzioni intelligenti che siano abbastanza semplici e con un impatto minimo. Lo stesso per la parte del server SQL: so che ci sono un paio di registri e SP di monitoraggio disponibili. Non ho ancora capito quali sono adatti alla mia situazione.
Un collega ha suggerito di serializzare i risultati su file binari/di testo e riversarli tutti in DB utilizzando Inserimento di massa da file flat ... Non è sicuro che si tratti di una soluzione valida. –
Non sono affatto un DBA, ma mi chiedo un paio di cose qui: 1) è la tua CPU che lo limita, o il disco? 2) il meccanismo di bloccaggio del DB consente effettivamente inserti paralleli? Se è limitato su disco e il DBMS non blocca più processi, è possibile provare a suddividere i dati da inserire su più dischi e a forzare i processi per inserirli. – syrion
E 'sufficiente dividere le query attraverso connessioni separate? Come reagisce a SQL Server, "fisicamente"? Gli inserti sono realmente scritti contemporaneamente nel DB, in varie posizioni di riga? –