题
我有很多问题,在新创建的空表中添加了一个简单的外键约束。参考表是一个很小的,其中少于40个记录,但引用了很多。
发生了什么:新表将成功创建,但是在添加FK约束时,它会在很长一段时间内“思考”并增加CPU负载。内存使用率增加,服务器开始像疯狂的分页开始,并变得无反应(连接超时)。取消查询无济于事。唯一有效的是重新启动服务器,这是非常昂贵的。
这是我要运行的脚本。我希望SQL Server Gurus可以提供帮助。谢谢!
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
编辑:引用是一张看起来像这样的小表:
[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
其他表(FK)经常引用column1ID。外部典型是另一个桌子的FK。问题发生在一个Alter Table调用中。不幸的是,这两个都是一起运行的,所以我无法说出哪一个造成了。
编辑:DB进入“思考”模式后,可以通过将其切换到单个模式,然后返回多用户模式来将其备份。它比重新启动服务器要好得多,但仍然无法接受。
解决方案
随机思考:您有任何交易开放吗?
Alter表将需要独家访问(就像大多数DDL一样),并且可能是由模式锁定的,这又会阻止引用可阻止引用,这又会阻止其他查询...
其他提示
我建议孤立地运行每个查询批次。
首先,创建表格,看看是否成功。
接下来,尝试使用自己添加外键约束 WITH NOCHECK
代替 WITH CHECK
. WITH NOCHECK
将抑制对内容的任何验证 MyNewTable.Column1ID
在创建约束时,在引用表的列中的值。如果 MyNewTable
是空的或几行,我认为这会产生太大影响,但是我遇到了像您描述的症状 - 除了桌子获得新约束的桌子上有数百万行。
最后,运行最后一批尝试设置 WITH CHECK
在您的新约束上。如果陷入困境,您可能只需要离开新的FK集 WITH NOCHECK
, ,但是不建议这样做,因为定义了约束 WITH NOCHECK
被查询优化器忽略,直到将它们设置回 WITH CHECK
.
如果此问题可重现,我建议您打开Microsoft支持案例。可能是一个错误,您正在击中它。如果发现这是一个已知的问题,他们将退还给您开案的费用。
少数需要研究的事情 - 不是解决方案,而是可能导致一些事情。
是否定义了任何触发因素?
在您创建新表格时使用或访问数据库,还是空闲?
在参考表中是否有任何内容(在部署或其他情况下)更新column1ID,还是在该表中删除行?
参考表中的column1ID上是否有主键或唯一约束? (您没有列出一个,但我认为如果不存在SQL,SQL会立即失败。)