Domanda

Ho una serie molto ampia di dati (~ 3 milioni di record) che devono essere uniti con aggiornamenti e nuovi record su un programma giornaliero.Ho una procedura memorizzata che effettivamente rompe il set di record in 1000 blocchi di registrazione e utilizza il comando MERGE con le tabelle TEMP in un tentativo di bloccare la tabella live mentre i dati stanno aggiornando.Il problema è che non aiuta esattamente.La tabella è ancora "blocca" e il nostro sito Web che utilizza i dati riceve timeout durante il tentativo di accedere ai dati.Ho persino provato a dividerlo in 100 blocchi di record e ho persino provato un WAITFOR DELAY '000:00:5' per vedere se avrebbe contribuito a mettere in pausa tra il fusione dei blocchi.È ancora piuttosto pigro.

Sto cercando suggerimenti, best practice o esempi su come unire grandi serie di dati senza bloccare le tabelle.

Grazie

È stato utile?

Soluzione

Modificare il front-end per utilizzare NOLOCK o leggere non confezionato quando si esegue il Seleziona .

Non è possibile che Nolock si unisce, inserire o aggiornare come i record devono essere bloccati per eseguire l'aggiornamento.Tuttavia, è possibile annullare le selezioni.

Nota che dovresti usarlo con cautela.Se letture sporche vanno bene, allora vai avanti.Tuttavia, se le letture richiedono i dati aggiornati, è necessario scaricare un percorso diverso e capire esattamente perché la fusione dei record 3M sta causando un problema.

Sarei disposto a scommettere che la maggior parte del tempo viene speso lettura dei dati dal disco durante il comando Merge e / o lavorando intorno a situazioni di memoria bassa.Potrebbe essere meglio semplicemente ripieno di più RAM nel tuo server di database.

Un importo ideale sarebbe quello di avere abbastanza RAM per estrarre l'intero database in memoria secondo necessità.Ad esempio, se si dispone di un database da 4 GB, assicurati di avere 8 GB di RAM .. in un server X64 ovviamente.

Altri suggerimenti

Ho paura di aver dell'esperienza opposta. Stavamo eseguendo aggiornamenti e inserzioni in cui il tavolo di origine aveva solo una frazione del numero di righe come il tavolo bersaglio, che era nei milioni.

Quando abbiamo combinato i record della tabella di origine su tutta la finestra operativa e poi abbiamo eseguito l'unione solo una volta, abbiamo visto un aumento del 500% delle prestazioni. La mia spiegazione per questo è che stai pagando per l'analisi anteriore su del comando di unione solo una volta invece di più e più volte in un loop stretto.

Inoltre, sono certo che fusione di 1,6 milioni di righe (fonte) in 7 milioni di righe (target), al contrario di 400 righe in 7 milioni di righe oltre 4000 distinte operazioni (nel nostro caso) sfrutta le funzionalità del motore SQL Server molto meglio. Ancora una volta, una buona quantità di lavoro è nell'analisi dei due set di dati e questo viene fatto solo una volta.

Un'altra domanda che devo chiedere è bene è se sarai consapevole che il comando di unione funzioni molto meglio con gli indici sia sulle tabelle di origine che di destinazione? Vorrei riferirti al seguente link:

http://msdn.microsoft.com /en-us/library/cc879317(v=sql.100).aspx

Dall'esperienza personale, il problema principale con unione è che poiché la pagina Blocca ha una concorrenza con la concorrenza nei tuoi inserti diretti a una tabella. Quindi, se vai giù questa strada è fondamentale che battiamo tutti gli aggiornamenti che colpiscono una tabella in un singolo scrittore.

Ad esempio: avevamo un tavolo in cui l'inserto ha preso un pazzo di 0,2 secondi per ingresso, la maggior parte di questa volta apparentemente essendo sprecata sulla chiusura delle transazioni, così ci siamo cambiati per usare unione e alcuni test rapidi hanno dimostrato che ci ha permesso di farlo Inserire 256 voci in 0,4 secondi o addirittura 512 In 0,5 secondi, abbiamo testato questo con i generatori di carico e tutto sembrava andare bene, fino a quando non ha colpito la produzione e tutto bloccato all'inferno sui blocchi della pagina, con conseguente throught total che con il Inserti individuali.

La soluzione era di non solo batch le voci da un singolo produttore in un'operazione di unione, ma anche a batch il lotto dai produttori che vanno al DB individuale in un'unica operazione di unione tramite un livello aggiuntivo di coda (in precedenza anche una singola connessione Per DB, ma usare Marte per interbleave tutti i produttori chiamano la stored procedure facendo la transazione di unione effettiva), in questo modo siamo stati quindi in grado di gestire molte migliaia di inserti al secondo senza problemi.

Avere il NOLOCK suggerisce su tutte le tue letture front-end è un must assoluto, sempre.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top