J'ai une table avec des millions de lignes et une colonne qui autorise les valeurs NULL. Cependant, aucune ligne n'a actuellement une valeur NULL pour cette colonne (je peux le vérifier assez rapidement avec une requête). Cependant, lorsque j'exécute la commande
ALTER TABLE MyTable ALTER COLUMN MyColumn BIGINT NOT NULL;
la requête prend une éternité relative. Cela prend en fait entre 10 et 20 minutes, plus de deux fois plus longtemps que l'ajout d'une contrainte de vérification. Existe-t-il un moyen de mettre à jour instantanément les métadonnées de la table pour cette colonne, d'autant plus que je sais qu'aucune ligne n'a de valeur NULL pour cette colonne?
sql-server-2008
null
alter-table
Joseph Daigle
la source
la source
Sch-M
verrou lorsque cela prend "pour toujours". Avez-vous regardé pour voir s'il était en attente ou occupé?Réponses:
La réponse de @ ypercube gère cela partiellement en tant que changement de métadonnées uniquement.
L'ajout de la contrainte
NOCHECK
signifie qu'aucune ligne ne devra être lue pour la vérifier, et si vous partez d'une position où la colonne ne contient pas deNULL
valeurs (et si vous savez qu'aucune ne sera ajoutée entre la vérification et l'ajout de la contrainte), alors, comme la contrainte empêche laNULL
création de valeurs à partir de futuresINSERT
ou d'UPDATE
opérations, cela fonctionnera.L'ajout de la contrainte peut cependant avoir un impact sur les transactions simultanées. Le
ALTER TABLE
devra d'abord acquérir uneSch-M
serrure. Pendant qu'il attend cela, tous les autres accès à la table seront bloqués comme décrit ici .Une fois le
Sch-M
verrou acquis, l'opération devrait cependant être assez rapide.Un problème avec cela est que même si vous savez que la colonne n'a pas de
NULL
s, la contrainte n'est pas approuvée par l'optimiseur de requête, ce qui signifie que les plans peuvent être sous-optimaux.Comparez cela avec le plus simple
Un problème possible que vous pourriez rencontrer avec la modification de la définition de colonne de cette manière est qu'il doit non seulement lire toutes les lignes pour vérifier qu'elles remplissent la condition, mais peut également finir par effectuer des mises à jour journalisées des lignes .
Une solution intermédiaire pourrait être d'ajouter la contrainte de vérification
WITH CHECK
. Cela sera plus lent queWITH NOCHECK
nécessaire pour lire toutes les lignes, mais cela permet à l'optimiseur de requête de donner le plan le plus simple dans la requête ci-dessus et il devrait éviter le problème de mises à jour enregistrées possibles.la source
Vous pouvez, au lieu de modifier la colonne, ajouter une
CHECK
contrainte de table avec l'NOCHECK
option:la source
NULL
mais ne pourraient pas être utilisées par l'optimiseur de requête.ALTER COLUMN
comme une fois leSch-M
verrou acquis, cela n'a pas besoin de balayer les lignes du tout). Je souligne simplement que ce n'est pas tout à fait la même chose (par exemple, s'il est utilisé dans uneNOT IN
requête, le plan sera plus complexe)