2013-07-09 42 views
12

Sto caricando grandi quantità di dati da un file di testo in SQL Server. Attualmente ogni record viene inserito (o aggiornato) in una transazione separata, ma questo lascia il DB in cattivo stato se un record fallisce.Limite dimensioni transazioni in SQL Server

Mi piacerebbe mettere tutto in una grande transazione. Nel mio caso, sto esaminando ~ 250.000 inserti o aggiornamenti e forse ~ 1.000.000 di query. Il file di testo è di circa 60 MB.

È irragionevole mettere l'intera operazione in un'unica transazione? Qual è il fattore limitante?

risposta

10

Non solo non è irragionevole farlo, ma è un dovere nel caso in cui si desidera preservare l'integrità nel caso in cui qualsiasi record fallisce, quindi si ottiene un'importazione "tutto o niente" come si nota. 250000 inserti o aggiornamenti non saranno un problema per SQL da gestire, ma vorrei dare un'occhiata a quelle che sono quelle milioni di query. Se non sono necessari per eseguire la modifica dei dati, li porterei fuori dalla transazione, quindi non rallentano l'intero processo.

È necessario considerare che quando si ha una transazione aperta (indipendentemente dalla dimensione), l'aspetto si verifica nelle tabelle che tocca e transazioni lunghe come la propria potrebbero causare il blocco in altri utenti che stanno cercando di leggerle allo stesso tempo. Se si prevede che l'importazione sia grande e dispendiosa in termini di tempo e il sistema sarà sotto carico, si consiglia di eseguire l'intero processo durante la notte (o eventuali ore non di punta) per mitigare l'effetto.

Informazioni sulla dimensione, non esiste un limite di dimensioni specifiche in SQL Server, possono teoricamente modificare qualsiasi quantità di dati senza problemi. Il limite pratico è in realtà la dimensione del file di registro delle transazioni del database di destinazione. Il motore DB memorizza tutti i dati temporanei e modificati in questo file mentre la transazione è in corso (quindi può essere utilizzata per il rollback, se necessario), quindi questo file aumenterà di dimensioni. Deve disporre di spazio libero sufficiente nelle proprietà del database e di spazio su disco sufficiente per la crescita del file. Inoltre, i blocchi di riga o tabella che il motore inserirà nelle tabelle interessate consuma memoria, quindi il server deve disporre di sufficiente memoria libera per tutti questi impianti idraulici. In ogni caso, 60 MB di dimensioni sono spesso troppo poco per preoccuparsi in generale. 250.000 righe sono considerevoli, ma non troppo, quindi qualsiasi server di dimensioni decenti sarà in grado di gestirlo.

0

Bene, personalmente, non carico mai i dati importati direttamente nelle tabelle dei miei prodotti e estirpo tutti i record che non passeranno prima di arrivare al punto di caricamento. Alcuni tipi di errori eliminano completamente l'importazione e altri potrebbero semplicemente inviare il record a una tabella di eccezioni per essere rispediti al provider e riparati per il prossimo caricamento. In genere ho una logica che determina se ci sono troppe eccezioni e uccide anche il pacchetto.

Ad esempio, supponiamo che la città sia un campo riusato nel database e nel file di 1.000.000 di record, ne hai dieci che non hanno città. Probabilmente è meglio inviarli a una tabella delle eccezioni e caricare il resto. Ma supponiamo che tu abbia 357.894 record senza città. Quindi potrebbe essere necessario avere una conversazione con il fornitore di dati per ottenere i dati corretti prima del caricamento. Interesserà certamente meno prod se è possibile determinare che il file è inutilizzabile prima di provare a influenzare le tabelle di produzione.

Inoltre, perché stai facendo questo record alla volta? Spesso è possibile andare molto più velocemente con l'elaborazione basata sui set, soprattutto se si è già riusciti a pulire i dati in anticipo. Ora potrebbe essere ancora necessario fare in lotti, ma un record alla volta può essere molto lento.

Se si desidera veramente eseguire il rollback dell'intera operazione in caso di errori di parte, si è necessario utilizzare le transazioni. Se si esegue questa operazione in SSIS, è possibile inserire le transazioni solo sulla parte del pacchetto in cui si influiscono sulle tabelle prod e non preoccuparsi di esse nella messa in scena dei dati e nelle parti di pulizia.

0

Non vi è alcun problema con l'esecuzione di un'operazione di volume completo o nulla, a meno che un rollback completo non sia problematico per la vostra azienda. In effetti, una singola transazione è il comportamento predefinito per molte utilità di inserimento di massa.

Vorrei fortemente sconsigliare una singola operazione per riga. Se si desidera eliminare i dati non validi, è possibile caricare prima i dati in una tabella di staging e determinare preventivamente i "dati non validi" e saltare tali righe.

3

SQL Server è in grado di gestire le transazioni di queste dimensioni. Utilizziamo una singola transazione per caricare in massa diversi milioni di record.

La parte più costosa di un'operazione di database è solitamente la connessione e il traffico del server client. Per gli inserti/aggiornamenti, l'indicizzazione e la registrazione sono anche costosi, ma è possibile attenuare tali costi utilizzando le tecniche di caricamento corrette (vedere di seguito). Vuoi davvero limitare la quantità di connessioni e dati trasferiti tra client e server.

A tal fine, è necessario considerare il caricamento in blocco dei dati utilizzando SSIS o C# con SqlBulkCopy. Una volta eseguito il caricamento collettivo di tutto, è possibile utilizzare le operazioni basate su set sul server per aggiornare o verificare i dati.

Dai un'occhiata a questa domanda per ulteriori suggerimenti sull'ottimizzazione dei carichi di dati. La domanda è correlata a C# ma molte informazioni sono utili per SSIS o altri metodi di caricamento. What's the fastest way to bulk insert a lot of data in SQL Server (C# client).

Problemi correlati