Per prima cosa: quanti dati ci sono nella tabella? Numero di righe e dimensioni della tabella?
Secondo: è possibile eseguire il backup e ripristinare questa tabella su un server di prova ed eseguire l'istruzione alter per vedere l'impatto (supponendo che non sia impossibile a causa della tabella troppo grande per adattarsi a un sistema non di produzione)? Trovo sempre che i test nel mio ambiente siano più precisi dei consigli delle interwebs poiché ci sono diversi fattori che possono influenzare il risultato che potrebbero non essere forniti nella domanda semplicemente perché non sanno che tali fattori potrebbero influenzare il risultato.
Terzo: aumentare le dimensioni di un campo di lunghezza variabile è (supponendo che non si superi il limite di 8060 byte) una semplice operazione di metadati poiché nessun dato reale cambierebbe per tale operazione. MA, d'altra parte, ridurre le dimensioni di un campo a lunghezza variabile, anche a qualcosa che funzionerà più che ovviamente, non è una semplice modifica dei metadati perché SQL Server non lo sa, prima di scansionare tutte le righe , che la dimensione appena richiesta è valida.
Quindi: Sì, questo bloccherà la tabella per un periodo di tempo . Quanto tempo? Bene, ecco il test che ho appena fatto:
Ho avuto, da alcuni altri test, una tabella con un singolo INT NOT NULL
campo e 1 milione di righe. L'ho copiato in una nuova tabella allo scopo di eseguire questo test tramite:
SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;
In questo modo stavo iniziando con uno scenario simile di avere un MAX
campo (mi sono appena reso conto che hai VARCHAR
e sto usando NVARCHAR
, ma ciò non dovrebbe alterare il comportamento che sto vedendo) in cui potrei cambiare 500
. E contiene dati che possono facilmente adattarsi a 500 caratteri. Ci sono voluti alcuni minuti.
Ho quindi eseguito:
ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
E ci sono voluti poco più di 11 minuti.
Ho rieseguito di nuovo il test, questa volta lasciando cadere il [ResizeTest]
tavolo e cambiando entrambi NVARCHAR
per essere giusto VARCHAR
, solo per essere super sicuro che sto confrontando le mele con qualcosa che almeno sembra una mela ;-).
La creazione della tabella iniziale ha richiesto 20 secondi mentre i ALTER TABLE
minuti 2.
Quindi, in termini di stima dei tempi di inattività, è davvero difficile da fare in quanto si basa sulla velocità di I / O del disco, se è necessario eseguire o meno operazioni di crescita automatica sul file di dati e / o sul registro delle transazioni, ecc. è probabilmente una grande parte del motivo per cui il mio primo test ha richiesto 11 minuti per essere modificato e il secondo, pur VARCHAR
essendo la metà della dimensione dei NVARCHAR
dati, ha impiegato solo 2 minuti (ovvero i file sono stati pre-sviluppati a quel punto). Tuttavia, dovresti tenere a mente che il mio test è in esecuzione sul mio laptop, che non è il disco più veloce, ma era anche solo 1 milione di righe di 2 piccole colonne (circa 22 byte per riga).
E poiché hai chiesto cosa farà alle pagine dei dati, ecco la tua risposta. Ho fatto un sp_spaceused
dopo aver creato il tavolo, dopo aver fatto il ALTER COLUMN
, e dopo averlo fatto ALTER TABLE dbo.ResizeTest REBUILD;
. I risultati (i seguenti numeri si basano sul secondo test usando VARCHAR
, non sul primo test usando NVARCHAR
):
After initial table creation: 526,344 KB
After ALTER COLUMN VARCHAR(500): 1,031,688 KB <--- !! Yikes!!
After ALTER REBUILD: 526,472 KB
Se sei preoccupato di dover mantenere l'operazione nel minor tempo possibile, consulta un articolo che ho scritto per fare proprio questo: Ristruttura 100 milioni di righe (o più) tabelle in secondi. SRSLY! (è richiesta la registrazione gratuita).
ALTER
ogni colonna in successione: ogni azione ha richiesto meno di un secondo. Quando furono terminati, il tavolo era raddoppiato in dimensioni, ma una volta che ho fatto un'operazioneREBUILD
(che era anche un'operazione di un secondo secondo), il tavolo è tornato alle sue dimensioni originali.