it-swarm.it

Aggiunta di colonne alle tabelle di produzione

Qual è il modo migliore per aggiungere colonne a tabelle di produzione di grandi dimensioni su SQL Server 2008 R2? Secondo i libri di Microsoft online:

Le modifiche specificate in ALTER TABLE vengono immediatamente implementate. Se le modifiche richiedono modifiche delle righe nella tabella, ALTER TABLE aggiorna le righe. ALTER TABLE acquisisce un blocco di modifica dello schema sulla tabella per assicurarsi che nessun altro collegamento faccia riferimento anche ai metadati per la tabella durante la modifica, ad eccezione delle operazioni di indice online che richiedono un blocco SCH-M molto breve alla fine.

(Http://msdn.Microsoft.com/en-us/library/ms190273.aspx)

Su una tabella di grandi dimensioni con milioni di righe, questo può richiedere del tempo. Prendere un'interruzione è l'unica opzione? Qual è il modo migliore per gestire questo tipo di situazione?

29
sh-beta

"Dipende"

Se aggiungi una colonna che non richiede l'aggiunta di dati alle righe, può essere abbastanza veloce.

Ad esempio, l'aggiunta di un int o char richiede movimenti fisici delle righe. L'aggiunta di un varchar nullable senza impostazione predefinita non dovrebbe (a meno che la bitmap NULL non debba espandersi)

È necessario provarlo su una copia ripristinata della produzione per ottenere un preventivo

La creazione di una nuova tabella, la copia e la ridenominazione potrebbero richiedere più tempo se è necessario aggiungere nuovamente indici e chiavi su una tabella da un miliardo di righe.

Ho modificato miliardi di tabelle di righe che impiegavano alcuni secondi per aggiungere una colonna nullable.

Ho detto di fare prima un backup?

27
gbn

Se la colonna è NULLable, l'impatto dovrebbe essere trascurabile. Se la colonna non può essere NULL e il valore deve essere impostato, può essere abbastanza diverso. Quello che farei in questo caso è, invece di aggiungere un vincolo non nullo e predefinito in un colpo solo, aggiungendo effettivamente dati ad ogni riga:

  • aggiungi la colonna come NULLable - dovrebbe essere veloce nella maggior parte dei casi
  • aggiorna i valori al valore predefinito
    • puoi farlo in batch se necessario
    • puoi anche usarlo per applicare la logica condizionale in cui alcune righe potrebbero non ottenere quelle predefinite
  • aggiungere i vincoli non nulli/predefiniti
    • questo sarà più veloce quando nessuno dei dati è NULL, ma dovrebbe essere comunque misurabile

Concorda con @gbn che puoi provarlo ripristinando una copia della produzione e provandola lì ... avrai una buona idea dei tempi (supponendo che l'hardware sia in qualche modo simile) e puoi anche vedere l'impatto sul registro delle transazioni.

21
Aaron Bertrand

Hai considerato:

  1. Creazione di una nuova tabella che include le modifiche alla definizione della tabella.
  2. Inserimento nella nuova definizione di tabella selezionando dalla tabella originale.
  3. Rinominare la tabella originale in _orig e quindi rinominare la nuova tabella con il nome della tabella originale.

Lo svantaggio è che è necessario disporre di spazio sufficiente nel database per apportare questa modifica. Potrebbe essere necessario un blocco di lettura sul tavolo per evitare letture sporche.

Tuttavia, si minimizza l'impatto per gli utenti finali se esiste la possibilità o la necessità di accedere contemporaneamente alla tabella originale. Dovrebbe anche ridurre al minimo la durata del blocco.

4
RobPaller

Ho un'eccezione speciale che ritengo debba essere menzionata.

Con SQL Server 2012 Enterprise e versioni successive, l'aggiunta di una nuova colonna NOT NULL con una costante di runtime è un'operazione online che viene completata istantaneamente e non dipende dal numero di righe nella tabella.

Ulteriori informazioni al riguardo sono disponibili in MSDN

Riprodurrò la sezione importante

A partire da SQL Server 2012 (11.x) Enterprise Edition, l'aggiunta di una colonna NOT NULL con un valore predefinito è un'operazione online quando il valore predefinito è una costante di runtime. Ciò significa che l'operazione viene completata quasi istantaneamente nonostante il numero di righe nella tabella. Perché, le righe esistenti nella tabella non vengono aggiornate durante l'operazione. Al contrario, il valore predefinito viene archiviato solo nei metadati della tabella e il valore viene cercato, se necessario, nelle query che accedono a queste righe.

1
rince