Augmentez la colonne de modification de la vitesse sur une grande table à NON NULL

12

J'ai récemment ajouté une colonne de bits NULL à une table qui compte près de 500 millions de lignes. Il n'y a pas de valeur par défaut sur la colonne, mais toutes les insertions spécifient une valeur de 0 ou 1, et j'ai exécuté une routine unique pour attribuer 0 ou 1 à toutes les lignes existantes (mise à jour des lignes par petits lots). Chaque ligne doit maintenant avoir un 0 ou 1 dans cette colonne.

Je veux rendre la colonne de bits non nulle, mais lorsque j'ai essayé de le faire via ALTER TABLE t1 ALTER COLUMN c1 bit not null, elle a commencé à fonctionner pendant 3 minutes et je l'ai arrêtée car elle bloquait toutes les lectures de la table et je soupçonnais que cela prendrait beaucoup de temps. . Il est possible que cela ne prenne pas trop de temps, mais je ne pouvais pas risquer trop d'indisponibilité. Le retour en arrière lui-même a pris 6 minutes.

Avez-vous des suggestions sur la façon de rendre la colonne non annulable sans que cela prenne potentiellement des heures? De plus, existe-t-il un moyen d'estimer la durée de la ALTER TABLE ALTER COLUMNdéclaration que j'ai commencée puis annulée?

J'utilise SQL Server 2017 Web Edition.

Ben Amada
la source

Réponses:

12

Au lieu de modifier la définition de colonne, vous pouvez ajouter un CHECK CONSTRAINTqui n'autorise pas les valeurs NULL pour cette colonne. Le tableau devra toujours être analysé, mais il n'aura pas besoin de modifier chaque page de données, ce devrait donc être une opération beaucoup plus rapide. Malheureusement, un verrou Sch-M sera toujours maintenu pendant l'opération. Une astuce consiste à essayer d'obtenir autant de la table dans le pool de mémoire tampon que possible avant d'essayer d'ajouter la contrainte. Cela peut réduire la durée de maintien du verrou Sch-M.

Vous pouvez ensuite supprimer la contrainte et modifier la définition de colonne lors de votre prochaine fenêtre de maintenance.

Joe Obbish
la source
Merci Joe pour l'idée. J'ai failli ajouter une contrainte de vérification, mais j'ai eu une fenêtre de maintenance pendant le week-end et j'ai pu modifier la colonne pour qu'elle ne soit pas annulable. Je ne sais pas si cela a aidé, mais pour essayer d'obtenir les données de la table dans le pool de tampons, juste avant de rendre la colonne non nullable, j'ai couru, SELECT c1, count(*) FROM t1 GROUP BY c1ce qui a pris environ 9 minutes pour s'exécuter. Il a ALTER TABLE ALTER COLUMNfallu 25 minutes pour terminer la déclaration proprement dite. Pas mal.
Ben Amada
11

Si vous utilisez Enterprise Edition (EE), une meilleure stratégie aurait pu être de l'ajouter comme NOT NULLavec une valeur par défaut de 0ou 1(selon la plus courante).

Il s'agit d'un changement de métadonnées uniquement dans EE . Mettez ensuite à jour ceux qui doivent être retournés. Cela signifie moins de mises à jour et pas besoin de modifier la nullité de la colonne une fois terminé. - martin-smith

utilisateur126897
la source
Fait intéressant, j'ai remarqué cette fonctionnalité la semaine dernière lorsque j'ai testé l'ajout d'une colonne de bits non nullable avec une valeur par défaut à cette même grande table sur ma machine locale qui exécute l'édition développeur SQL - la colonne a été ajoutée instantanément et je n'ai pas pu comprendre pourquoi . C'est plus tard lui que ça doit être parce que l'édition développeur inclut des fonctionnalités EE.
Ben Amada
-3

Essayez de copier les données dans une nouvelle table, puis renommez-la. Vous devez prendre soin de toutes les contraintes et index. C'est ce que fait le concepteur de tables SSMS lorsque vous souhaitez réorganiser les colonnes (par exemple), mais vous devez vérifier le script pour voir s'il y a quelque chose qui ne semble pas correct.

Pendant la copie, l'accès en lecture à la table source n'est pas un problème, mais s'il y a des écritures, elles peuvent être bloquées ou non copiées, selon le niveau d'isolement.

Razvan Socol
la source