A resposta do @ ypercube gerencia isso parcialmente, pois apenas os metadados são alterados.
Adicionar a restrição NOCHECK
significa que nenhuma linha precisará ser lida para verificá-la e, se você estiver começando em uma posição em que a coluna não contém NULL
valores (e se você souber que nenhuma será adicionada entre verificar e adicionar a restrição), como a restrição impede a NULL
criação de valores do futuro INSERT
ou das UPDATE
operações, isso funcionará.
A adição da restrição ainda pode ter impacto nas transações simultâneas. A ALTER TABLE
necessidade de adquirir um Sch-M
bloqueio primeiro. Enquanto aguarda, todos os outros acessos à tabela serão bloqueados conforme descrito aqui .
Uma vez que o Sch-M
bloqueio é adquirido, a operação deve ser bastante rápida.
Um problema com isso é que, mesmo que você saiba que a coluna não possui, NULL
a restrição não é confiável pelo otimizador de consultas, o que significa que os planos podem ficar abaixo do ideal.
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)
Compare isso com o mais simples
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Um possível problema que você pode encontrar ao alterar a definição da coluna dessa maneira é que ela não apenas precisa ler todas as linhas para verificar se elas atendem à condição, mas também pode acabar realmente executando atualizações registradas nas linhas .
Uma casa possível a meio caminho pode ser adicionar a restrição de verificação WITH CHECK
. Isso será mais lento do WITH NOCHECK
que o necessário para ler todas as linhas, mas permite que o otimizador de consultas forneça o plano mais simples na consulta acima e evite o possível problema de atualizações registradas.