La risposta di @ ypercube lo gestisce parzialmente solo come modifica dei metadati.
L'aggiunta del vincolo con NOCHECK
significa che non sarà necessario leggere le righe per verificarlo e, se si parte da una posizione in cui la colonna non contiene NULL
valori (e se si conosce che non verrà aggiunto nessuno tra il controllo e l'aggiunta del vincolo), poiché il vincolo impedisce la NULL
creazione di valori futuri INSERT
o UPDATE
operazioni, funzionerà.
L'aggiunta del vincolo può comunque avere un impatto sulle transazioni simultanee. L' ALTER TABLE
avrà bisogno di acquisire un Sch-M
blocco di prima. Durante l'attesa, tutti gli altri accessi alle tabelle verranno bloccati come descritto qui .
Una volta Sch-M
acquisito il blocco, l'operazione dovrebbe essere piuttosto rapida.
Un problema con questo è che anche se si conosce che la colonna in realtà non ha NULL
s il vincolo non è attendibile dal Query Optimizer, il che significa che i piani possono essere non ottimali.
CREATE TABLE T (X INT NULL)
INSERT INTO T
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values
ALTER TABLE T WITH NOCHECK
ADD CONSTRAINT X_NOT_NULL
CHECK (X IS NOT NULL) ;
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Confronta questo con il più semplice
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Un possibile problema che potresti riscontrare con l'alterazione della definizione di colonna in questo modo è che non solo è necessario leggere tutte le righe per verificare che soddisfino la condizione, ma può anche finire per eseguire effettivamente gli aggiornamenti registrati alle righe .
Una possibile casa a metà strada potrebbe essere quella di aggiungere il vincolo di controllo WITH CHECK
. Questo sarà più lento di WITH NOCHECK
quanto deve leggere tutte le righe ma consente all'ottimizzatore di query di fornire il piano più semplice nella query sopra e dovrebbe evitare il possibile problema degli aggiornamenti registrati.