我将向您介绍一个示例,以便您了解为什么花了很长时间。为此测试创建一个空数据库。
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
在人员表上创建外键约束。
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;
提交插入操作后,放置约束将立即完成,因为现在放置语句可以获取所需的锁。
对于您的情况,您需要确保没有会话持有兼容的锁,这将防止放置约束来获取必要的锁。