Question

Je veux modifier un champ d'une table qui a environ 4 millions de disques. Je me suis assuré que tous ces champs sont des valeurs NOT NULL et que vous souhaitez modifier ce champ NOT NULL

ALTER TABLE dbo.MyTable
ALTER COLUMN myColumn int NOT NULL

... semble prendre une éternité pour faire cette mise à jour. Tous les moyens de l'accélérer ou suis-je coincé juste le faire du jour au lendemain en dehors des heures?

pourrait également cette cause un verrou de table?

Était-ce utile?

La solution

Vous pouvez modifier un champ et de le rendre non nul sans elle vérifier les champs. Si vous êtes vraiment inquiet de ne pas le faire en dehors des heures que vous pouvez ajouter une contrainte au champ qui vérifie pour vous assurer qu'il est non nul à la place. Cela vous permettra d'utiliser l'option sans contrôle, et ne pas avoir le vérifier chacun des 4 millions de lignes pour voir si elle met à jour.

CREATE TABLE Test
(
    T0 INT Not NULL,
    T1 INT NUll 
)

INSERT INTO Test VALUES(1, NULL) -- Works!

ALTER TABLE Test
    WITH NOCHECK
        ADD CONSTRAINT N_null_test CHECK (T1 IS NOT NULL)

    ALTER COLUMN T1 int NOT NULL 

INSERT INTO Test VALUES(1, NULL) -- Doesn't work now!

Vraiment, vous avez deux options (ajouté un troisième voir édition):

  1. Utiliser la contrainte qui empêchera toute nouvelle lignes d'être mis à jour et laisser les originaux inchangés.
  2. Mise à jour des lignes qui sont null à autre chose et ensuite appliquer l'option alter non nulle. Cela devrait vraiment être exécuté en dehors des heures, à moins que vous ne me dérange pas de processus étant verrouillés de la table.

En fonction de votre scénario spécifique, l'une des options pourrait être mieux pour vous. Je ne voudrais pas choisir l'option parce que vous devez l'exécuter en dehors des heures bien. À long terme, le temps passé à la mise à jour au milieu de la nuit sera bien dépensé comparé les maux de tête que vous aurez peut-être faire face en prenant un raccourci pour sauver quelques heures.

Tout cela étant dit, si vous allez aller avec l'option deux, vous pouvez réduire la quantité de travail que vous faites en dehors des heures. Puisque vous devez vous assurer que vous mettez à jour les lignes à ne pas nulle avant de modifier la colonne, vous pouvez écrire un curseur lentement (par rapport à le faire à la fois)

  1. Passez par chaque ligne
  2. Vérifiez si elle est nulle
  3. Mise à jour de façon appropriée. Cela prendra un bon moment, mais il ne se verrouille pas le bloc de tablée d'autres programmes d'y accéder. (Ne pas oublier le avec (tolet) tableau indice!)

EDIT : Je viens de penser à une troisième option:   Vous pouvez créer une nouvelle table avec les colonnes appropriées, puis exporter les données de la table d'origine vers le nouveau. Lorsque cela est fait, vous pouvez alors déposer la table d'origine et changer le nom du nouveau être l'ancien. Pour ce faire, vous devrez désactiver les dépendances sur l'original et les remettre sur le nouveau lorsque vous avez terminé, mais ce processus permettra de réduire considérablement la quantité de travail que vous avez à faire dans les heures de repos. Ceci est la même approche que le serveur SQL utilise lorsque vous modifiez la commande de colonne aux tables par le studio de gestion. Pour cette approche, je ferais l'insert en morceaux pour vous assurer que vous ne cause pas annuler le stress sur le système et empêcher les autres d'y accéder. Puis les heures de repos, vous pouvez déposer l'original, renommer la seconde, et appliquer les dépendances, etc. Vous aurez encore quelques heures de congé, mais il sera minuscule par rapport à l'autre approche.

Lien à l'utilisation sp_rename .

Autres conseils

La seule façon de le faire « rapidement » (*) que je connais est par

  • créer une table 'ombre' qui a la disposition requise
  • ajouter un élément déclencheur à la source de table pour toute insertion / mise à jour / suppression des opérations sont copiés dans l'ombre table (esprit pour attraper de tout NULL qui pourrait apparaitre!)
  • copier toutes les données de la source à l'ombre table, potentiellement en morceaux assez petits (assurez-vous que vous pouvez gérer les données déjà copiées par le déclencheur (s), assurez-vous que les données s'adapter à la nouvelle structure (ISNULL ( ?)!)
  • scripter toutes les dépendances de / vers d'autres tables
  • quand tout est fait, procédez comme suit dans une transaction explicite:
    • obtenir un verrou de table exclusif sur la source table et un sur le shadowtable
    • exécuter les scripts d'abandonner les dépendances à la source table
    • renommer la source de table pour quelque chose d'autre (par exemple le suffixe _old)
    • renommer la table d'ombre au nom d'origine de la source table
    • exécuter les scripts pour créer toutes les dépendances à nouveau

Vous pouvez faire la dernière étape en dehors de la transaction car cela peut prendre un peu de temps, selon la quantité et la taille des tableaux faisant référence à ce tableau, les premières étapes ne prendra pas beaucoup de temps

Comme toujours, il est probablement préférable de faire un essai sur un serveur de test first =)

PS:. S'il vous plaît ne soyez pas tenté de recréer le FK avec son NOCHECK, elle les rend vaine que l'optimiseur ne sera pas leur faire confiance, ni les considérer lors de la construction d'un plan de requête

(*: où vient rapidement jusqu'à: avec le moins possible les temps d'arrêt)

Désolé pour le découragement, mais:

  • Les moyens pour l'accélérer: Non, pas si vous voulez changer la structure de la table elle-même
  • ou suis-je coincé fais juste la nuit pendant les heures creuses? Oui, et c'est probablement le meilleur, comme @HLGEM a souligné
  • pourrait également cette cause un verrou de table? Oui

Pas directement pertinent pour vous (parce que ça va au sujet de NOT NULL à NULL), mais lecture intéressante sur ce sujet: http://beyondrelational.com/blogs/sankarreddy/archive/2011/04/ 05 / est-alter-table alter-colonne non nULL à nULL toujours-expensive.aspx

Et enfin une histoire ancienne - sur une question équivalente dans un forum en 2005, la même proposition a été faite comme ci-dessus offerte @ Kevin - en utilisant une contrainte insteadof faisant la colonne elle-même non annulable: http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=50671

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top