J'ai créé un script qui, une à la fois, supprime toutes les clés étrangères d'une base de données, comme ceci:
ALTER TABLE MyTable1 DROP CONSTRAINT FK_MyTable1_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col2
Ce qui me surprend, c'est que le script prend beaucoup de temps: en moyenne, 20 secondes pour chaque DROP FK. Maintenant, je comprends que la création d'un FK peut être un gros problème, car le serveur doit aller vérifier que la contrainte FK n'est pas violée depuis le début, mais qu'elle tombe? Que fait un serveur lors de la suppression de FK qui prend si longtemps? C'est à la fois pour ma propre curiosité et pour comprendre s'il existe un moyen d'accélérer les choses. Pouvoir supprimer FK (et pas seulement les désactiver) me permettrait d'être beaucoup plus rapide lors d'une migration, et donc de minimiser les temps d'arrêt.
sql-server
foreign-key
sql-server-2016
carlo.borreo
la source
la source
Réponses:
La suppression d'une contrainte nécessite un verrou Sch-M (modification de schéma) qui empêchera les autres d'interroger la table pendant la modification. Vous attendez probablement pour obtenir ce verrou et devez attendre que toutes les requêtes en cours d'exécution sur cette table soient terminées.
Une requête en cours d'exécution a un verrou Sch-S (stabilité du schéma) sur la table et ce verrou est incompatible avec un verrou Sch-M.
Depuis les modes de verrouillage, les verrous de schéma
la source
Sch-S
verrou, et je soupçonne que c'est la cause première des problèmes de l'OP.Je vais vous guider à travers un exemple donc, vous pouvez voir pourquoi cela prenait beaucoup de temps. Création d'une base de données vide pour ce test.
Création de 2 tables.
Création d'une contrainte de clé étrangère sur la table Personne.
Insérez des données dans les deux tableaux.
Ouvrez une nouvelle fenêtre de requête et exécutez-la (ne fermez pas la fenêtre une fois la requête terminée).
Ouvrez une autre fenêtre de requête et exécutez-la.
Vous verrez que vous supprimez la contrainte continuera à fonctionner (en attente) et exécutez maintenant la requête pour voir pourquoi elle s'exécute plus longtemps et quels verrous elle attend.
Une fois que vous avez validé votre opération d'insertion, la contrainte de suppression se termine immédiatement car l'instruction de suppression peut désormais acquérir le verrou requis.
Pour votre cas, vous devez vous assurer qu'aucune session ne détient un verrou compatible, ce qui empêchera la contrainte de chute d'acquérir le ou les verrous nécessaires.
la source