Tsql 添加外键约束会占用内存并导致分页

Tsql 添加外键约束会占用内存并导致分页,tsql,sql-server-2008-r2,Tsql,Sql Server 2008 R2,向新创建的空表添加简单的外键约束有很多问题。引用表是一个很小的表,里面只有不到40条记录,但它被引用的次数很多 结果如下:新表创建成功,但添加FK约束时,它会“思考”很长时间,并增加CPU负载。内存使用量增加,服务器疯狂地开始分页并变得无响应(连接超时)。取消查询没有帮助。唯一有效的方法是重新启动服务器,这是非常昂贵的 这是我试图运行的脚本。我希望SQL server专家能够提供帮助。谢谢 USE [my_db] GO SET ANSI_NULLS ON GO SET QUOTED_IDEN

向新创建的空表添加简单的外键约束有很多问题。引用表是一个很小的表,里面只有不到40条记录,但它被引用的次数很多

结果如下:新表创建成功,但添加FK约束时,它会“思考”很长时间,并增加CPU负载。内存使用量增加,服务器疯狂地开始分页并变得无响应(连接超时)。取消查询没有帮助。唯一有效的方法是重新启动服务器,这是非常昂贵的

这是我试图运行的脚本。我希望SQL server专家能够提供帮助。谢谢

USE [my_db]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[MyNewTable](
    [Column1ID] [int] NOT NULL,
    [Column2ID] [int] NOT NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[MyNewTable]  WITH CHECK ADD  CONSTRAINT [FK_MyNewTable_Column1ID] FOREIGN KEY([Column1ID])
REFERENCES [dbo].[ReferenceTable] ([Column1ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[MyNewTable] CHECK CONSTRAINT [FK_MyNewTable_Column1ID]
GO
EDIT:ReferenceTable是一个小表,如下所示:

[Column1ID] [int] IDENTITY(1,1) NOT NULL,
[TxtCol1] [varchar](50) NOT NULL,
[TxtCol2] [varchar](50) NOT NULL,
[TxtCol3] [varchar](200) NOT NULL,
[TxtCol4] [nvarchar](2000) NOT NULL,
[TxtCol5] [varchar](200) NOT NULL,
[BitCol1] [bit] NOT NULL,
[TxtCol6] [varchar](200) NOT NULL,
[NumCol1] [smallint] NOT NULL,
[ExternalColumnId] [int] NOT NULL,
[NumCol2] [int] NOT NULL
Column1ID经常被其他表(FK)引用。ExternalColumnId是另一个表的FK。问题发生在一个ALTER TABLE调用期间。不幸的是,这两个都是一起运行的,所以我不能说是哪一个导致了它


编辑:一旦数据库进入“思考”模式,就可以将其切换到单用户模式,然后再切换回多用户模式。这比重新启动服务器要好得多,但仍然不可接受。

随机思考:您有没有打开的事务


ALTER表需要独占访问(大多数DDL也是如此),它可能被模式锁阻止,模式锁反过来会阻止ReferenceTable,而模式锁反过来又会阻止其他查询

我建议单独运行每个查询批处理

首先,创建表并查看是否成功

接下来,尝试使用带有NOCHECK的
而不是带有CHECK的
单独添加外键约束<创建约束时,使用NOCHECK的code>将禁止对MyNewTable.Column1ID中的内容与引用表列中的值进行任何验证。如果
MyNewTable
为空或只有很少的行,我认为这不会有多大影响,但我遇到了与您描述的症状类似的症状——除了获得新约束的表中有数百万行之外


最后,运行上一批,尝试在新约束上使用CHECK设置
。如果出现这种情况,您可能只需要将新的FK集合
保留为NOCHECK
,但是不建议这样做,因为使用NOCHECK
定义的约束将被查询优化器忽略,直到使用CHECK
将其设置为
,如果此问题是可重现的,我建议您打开Microsoft支持案例。可能是一只虫子,而你正在攻击它。如果发现这是一个已知的问题,他们会退还你打开案件的费用。

有一些事情需要研究——不是解决方案,但它们可能会导致一些问题

是否定义了任何触发器

在创建新表时是否正在使用或访问数据库,还是数据库处于空闲状态

是否(在部署时或其他情况下)更新引用表中的Column1ID,或删除该表中的行


引用表中Column1ID是否有主键或唯一约束?(您没有列出一个,但我认为如果没有一个,SQL将立即失败。)

奇怪。可引用的
的定义是什么?在哪句话之后,一切都会出错?
addconstraint
one?刚刚添加了更多信息。我在原始表中没有的一件事是主键。考虑到新表是空的,你知道这会有多大影响吗?Gbn是对的,我很确定你在看对象锁。它是可复制的。我对sqlserver了解不够,但您可以尝试创建一个新的表空间,由安装的驱动器中的数据文件提供服务,并检查问题是否存在。(我假设oracle和sqlserver有相似之处;))在咨询我的同事后,看起来数据库备份正在同时运行。但是考虑到参考表有多小(~40条记录),它会导致这样的问题吗?。。。我认为锁不会导致CPU或内存使用量显著增加…@pascal:它可以;锁需要资源,一个长事务可能会导致LDF增长,可能会有更多的检查点处理,暂停的线程被阻塞但有自己的锁…很好的解释,我已经在暂停的线程上运行了cpu时钟至少两次(或更多)