เหตุใดการวางกุญแจต่างประเทศจึงใช้เวลานาน?


13

ฉันได้สร้างสคริปต์ที่หนึ่งครั้งลบกุญแจต่างประเทศทั้งหมดจากฐานข้อมูลเช่นนี้:

ALTER TABLE MyTable1 DROP CONSTRAINT FK_MyTable1_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col2

สิ่งที่ทำให้ฉันประหลาดใจคือสคริปต์ใช้เวลานาน: โดยเฉลี่ย 20 วินาทีสำหรับแต่ละ DROP FK ตอนนี้ฉันเข้าใจว่าการสร้าง FK อาจเป็นเรื่องใหญ่เพราะเซิร์ฟเวอร์ต้องดำเนินการและตรวจสอบว่าข้อ จำกัด FK ไม่ได้ถูกละเมิดตั้งแต่เริ่มแรก แต่เป็นการลดลงใช่ไหม เซิร์ฟเวอร์ทำอะไรเมื่อปล่อย FKs ที่ใช้เวลานาน นี่เป็นทั้งความอยากรู้อยากเห็นของฉันเองและเพื่อให้เข้าใจว่ามีวิธีที่จะทำให้สิ่งต่าง ๆ เร็วขึ้นหรือไม่ ความสามารถในการลบ FK (ไม่ใช่แค่ปิดการใช้งาน) จะช่วยให้ฉันเร็วขึ้นมากในระหว่างการย้ายข้อมูลและลดเวลาหยุดทำงาน


1
อาจเป็นกระบวนการอื่นที่ล็อคสคีมาที่ใช้ร่วมกันบนฐานข้อมูลของคุณบังคับให้กระบวนการ FK ดร็อปรอให้กระบวนการเหล่านั้นเสร็จสิ้น ลองเรียกใช้ FK ดร็อปแล้วตรวจสอบ sp_who2 ทันทีเพื่อทำการบล็อก
Daniel Hutmacher

ฉันลืมที่จะพูดถึงไม่มีกระบวนการอื่นที่ทำงานบนฐานข้อมูลนี้ แต่มีอยู่ในฐานข้อมูลอื่น ๆ บนเซิร์ฟเวอร์เดียวกัน
carlo.borreo

คำตอบ:


12

การปล่อยข้อ จำกัด ต้องใช้การล็อค Sch-M (Schema Modification) ที่จะบล็อกผู้อื่นเพื่อสืบค้นตารางในระหว่างการปรับเปลี่ยน คุณอาจรอการล็อคและต้องรอจนกว่าแบบสอบถามที่กำลังเรียกใช้ทั้งหมดในตารางนั้นจะเสร็จสิ้น
แบบสอบถามที่กำลังทำงานอยู่มีการล็อค Sch-S (Schema Stability) บนตารางและตัวล็อคนั้นไม่สามารถทำงานร่วมกับตัวล็อค Sch-M ได้

จากโหมดล็อคล็อค Schema

กลไกจัดการฐานข้อมูลใช้การล็อค schema การแก้ไข (Sch-M) ในระหว่างการดำเนินการภาษาตารางข้อมูลคำจำกัดความ (DDL) เช่นการเพิ่มคอลัมน์หรือวางตาราง ในช่วงเวลาที่มีการล็อค Sch-M ป้องกันการเข้าถึงตารางพร้อมกัน ซึ่งหมายความว่าล็อค Sch-M จะบล็อกการทำงานภายนอกทั้งหมดจนกระทั่งล็อคถูกปลด

การดำเนินงาน data manipulation language (DML) บางอย่างเช่นการตัดทอนตารางใช้การล็อค Sch-M เพื่อป้องกันการเข้าถึงตารางที่ได้รับผลกระทบจากการทำงานพร้อมกัน

โปรแกรมฐานข้อมูลใช้การล็อคแบบแผนเสถียรภาพ (Sch-S) เมื่อรวบรวมและดำเนินการแบบสอบถาม ล็อค Sch-S ไม่ได้ล็อคการทำธุรกรรมใด ๆ รวมถึงล็อคเอกสิทธิ์ (X) ดังนั้นธุรกรรมอื่น ๆ รวมถึงรายการที่มีการล็อก X บนตารางจะยังคงทำงานต่อไปในขณะที่กำลังรวบรวมแบบสอบถาม อย่างไรก็ตามการดำเนินการ DDL พร้อมกันและการดำเนินการ DML พร้อมกันที่ได้รับการล็อค Sch-M ไม่สามารถดำเนินการบนตาราง


บางครั้งการเน้นตารางใน SSMS จะสร้างการSch-Sล็อกและฉันสงสัยว่านี่เป็นสาเหตุของปัญหาของ OP
John Eisbrener

5

ฉันจะแนะนำคุณผ่านตัวอย่างดังนั้นคุณจะเห็นว่าทำไมมันใช้เวลานาน สร้างฐานข้อมูลเปล่าสำหรับการทดสอบนี้

CREATE DATABASE [TestFK]
GO

สร้าง 2 ตาราง

 USE [TestFK]
 GO
CREATE TABLE dbo.[Address] (
      ADDRESSID   INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
       Address1    VARCHAR(50),
      City        VARCHAR(50),
      [State]     VARCHAR(10),
      ZIP     VARCHAR(10));
GO

CREATE TABLE dbo.Person (
       PersonID    INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
       LastName    VARCHAR(50) NOT NULL,
     FirstName   VARCHAR(50),
      AddressID   INT);
GO

การสร้างข้อ จำกัด Foreign Key ในตาราง Person

 USE [TestFK]
 GO
ALTER TABLE dbo.Person ADD CONSTRAINT FK_Person_AddressID FOREIGN KEY (AddressID)
REFERENCES dbo.Address(AddressID)
GO

แทรกข้อมูลบางส่วนลงในทั้งสองตาราง

USE [TestFK]
GO
INSERT dbo.Address (Address1,City,[State],Zip)
  SELECT '123 Easy St','Austin','TX','78701'
    UNION
 SELECT '456 Lakeview','Sunrise Beach','TX','78643'
GO
INSERT dbo.Person (LastName,FirstName,AddressID)
    SELECT 'Smith','John',1
   UNION
 SELECT 'Smith','Mary',1
   UNION
 SELECT 'Jones','Max',2
GO

เปิดหน้าต่างแบบสอบถามใหม่และเรียกใช้สิ่งนี้ (อย่าปิดหน้าต่างเมื่อแบบสอบถามเสร็จสมบูรณ์)

   USE [TestFK]
   GO
   BEGIN TRAN
   INSERT dbo.Person (LastName,FirstName,AddressID)
    SELECT 'Smith1','John1',1
    UNION
    SELECT 'Smith1','Mary1',1
    UNION
    SELECT 'Jones1','Max1',2

เปิดหน้าต่างแบบสอบถามอื่นและเรียกใช้สิ่งนี้

USE [TestFK]
GO
ALTER TABLE dbo.person DROP CONSTRAINT FK_Person_AddressID

คุณจะเห็นว่าคุณมีข้อ จำกัด การปล่อยจะยังคงทำงานต่อไป (รอ) และตอนนี้เรียกใช้แบบสอบถามเพื่อดูว่าทำไมมันทำงานอีกต่อไปและสิ่งที่ล็อคมันกำลังรอ

SELECT * FROM sys.dm_os_waiting_tasks 
WHERE blocking_session_id IS NOT NULL; 

เมื่อคุณส่งการดำเนินการแทรกข้อ จำกัด การปล่อยจะเสร็จสมบูรณ์ทันทีเนื่องจากตอนนี้คำสั่งดร็อปสามารถรับการล็อกที่ต้องการ

สำหรับกรณีของคุณคุณต้องตรวจสอบให้แน่ใจว่าไม่มีเซสชันใดกำลังถือล็อคที่เข้ากันได้ซึ่งจะป้องกันข้อ จำกัด การปล่อยเพื่อรับล็อค / ล็อคที่จำเป็น


ไม่มีใครใช้ฐานข้อมูล แต่ในทางกลับกันฉันไม่สามารถแยกว่าฉันมีหน้าต่างเปิดในฐานข้อมูลนี้ ฉันจะทำการทดลองอื่น
carlo.borreo

1
เมื่อคำสั่งการปล่อยของคุณกำลังรอให้เสร็จสิ้นให้เรียกใช้แบบสอบถามนี้จากหน้าต่างอื่น ที่จะให้สิ่งที่คุณรอ ได้รับการสอบถามจากที่นี่ มันมีรายละเอียดมากกว่าสิ่งที่ฉันให้ในตัวอย่างของฉัน
SqlWorldWide
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.