6

我在向新创建的空表添加简单的外键约束时遇到了很多问题。参考表是一个很小的表,其中只有不到 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

编辑: 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 调用之一期间。不幸的是,这两个是一起运行的,所以我无法说是哪一个引起的。

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

4

4 回答 4

4

胡思乱想:你有任何交易开放吗?

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

于 2010-12-06T19:08:07.873 回答
0

我建议单独运行每个查询批次。

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

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

最后,运行最后一批以尝试设置WITH CHECK新约束。如果这陷入困境,您可能只需要保留新的 FK set WITH NOCHECK,但是不建议这样做,因为WITH NOCHECK查询优化器会忽略定义的约束,直到将它们设置回WITH CHECK.

于 2011-01-24T03:14:26.300 回答
0

如果此问题可重现,我建议您打开 Microsoft 支持案例。可能是它是一个错误,你正在击中它。如果发现这是一个已知问题,他们将退还您打开案件的费用。

于 2011-01-28T14:34:53.793 回答
0

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

是否定义了任何触发器?

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

是否(在部署时或其他时间)更新参考表中的 Column1ID,或删除该表中的行?

引用表中的 Column1ID 上是否存在主键或唯一约束?(你没有列出一个,但我认为如果一个不存在,SQL 会立即失败。)

于 2011-01-28T14:46:17.993 回答