2012-05-25 14 views
14

Ho una tabella in SQL Server 2008 R2 con quasi un miliardo di righe. Voglio cambiare il tipo di dati di due colonne da int a bigint. Due volte ALTER TABLE zzz ALTER COLUMN yyy funziona, ma è molto lento. Come posso accelerare il processo? Stavo pensando di copiare i dati su un'altra tabella, rilasciare, creare, copiare e passare alla modalità di ripristino semplice o in qualche modo farlo con un cursore di 1000 righe alla volta, ma non sono sicuro che quelli porteranno effettivamente a miglioramenti.Modifica tipi di colonna in una tabella enorme

+1

Puoi spiegare che cosa stai modificando il tipo di dati da e verso? –

+1

Non riesco a vedere come si può usare un cursore per cambiare il tipo di colonna? Un tipo di colonna è una modifica a tutti i valori di una tabella. – Oded

+0

ints to bigints – user1417408

risposta

26

A seconda del cambiamento che si sta apportando, a volte può essere più semplice eseguire una finestra di manutenzione. Durante quella finestra (dove nessuno dovrebbe essere in grado di modificare i dati nella tabella) è possibile:

  1. calo gli indici/vincoli che punta alla vecchia colonna e trigger disabilitare
  2. aggiungere un nuovo nullable colonna con il nuovo tipo di dati (anche se è destinato a NON essere NULL)
  3. aggiorna la nuova colonna impostandola uguale al valore della vecchia colonna (e puoi farlo in blocchi di singole transazioni (ad esempio, influendo su 10000 righe a una ora usando UPDATE TOP (10000) ... SET newcol = oldcol WHERE newcol IS NULL) e con CHECKPOINT per evitare di sovraccaricare il registro)
  4. una volta che gli aggiornamenti sono tutti fatti, eliminare la vecchia colonna
  5. rinominare la nuova colonna (e aggiungere un vincolo NOT NULL, se del caso)
  6. ricostruire gli indici e le statistiche di aggiornamento

La chiave qui è che ti permette per eseguire l'aggiornamento in modo incrementale nel passaggio 3, che non è possibile eseguire in un singolo comando ALTER TABLE.

Ciò presuppone che la colonna non stia giocando un ruolo importante nell'integrità dei dati - se è coinvolta in un gruppo di relazioni con le chiavi esterne, ci sono più passaggi.

EDIT

Inoltre, e solo chiedendo ad alta voce, non ho fatto alcun test per questo (ma aggiungendo alla lista). Mi chiedo se la compressione di pagina + riga potrebbe aiutare qui? Se si modifica un INT in un BIGINT, con compressione in atto, SQL Server deve comunque trattare tutti i valori come se fossero ancora inseriti in un INT. Ancora una volta, non ho provato se questo avrebbe reso un cambiamento più veloce o più lento, o quanto tempo ci sarebbe voluto per aggiungere la compressione in primo luogo. Lascialo fuori.

+0

Il DB sarà offline. Imposterà il modello di recupero come aiuto semplice? – user1417408

+0

In SIMPLE o FULL, l'enorme comando ALTER TABLE non sarà diverso, poiché l'intero processo viene registrato in entrambi i casi. Con quanto sopra, SIMPLE potrebbe essere un po 'meglio, ma il modello di recupero non dovrebbe avere importanza se si seleziona una dimensione di batch appropriata. Anche se il database è "offline" (presumo che tu non intenda ALTER DATABASE ... SET OFFLINE), perché la velocità è importante? Quanto sopra dovrebbe probabilmente radere una certa percentuale di tempo, ma non sarà incredibilmente più veloce. Quello che stai facendo richiede semplicemente tempo. –

+0

Aaron, grazie per il tuo aiuto. La velocità è importante perché il sito che utilizza questo DB sarà offline solo per alcune ore. – user1417408

-2

Se si utilizza qualcosa come SQL Server Management Studio, basta andare alla tabella nel database, fare clic con il tasto destro, selezionare "Progettazione" e quindi scegliere la colonna che si desidera modificare: impostarla su bigint e premere Salva. Cambia l'intera colonna, ma i valori precedenti rimarranno come sono. Questo è utile per consentire a una tabella di "crescere fuori" da int in bigint, ma non cambierà i dati esistenti per quanto ne so.

Problemi correlati