Добавление ограничения внешнего ключа высасывает память и вызывает подкачку - PullRequest
6 голосов
/ 06 декабря 2010

У меня много проблем с добавлением простого ограничения внешнего ключа во вновь созданную пустую таблицу.Справочная таблица - крошечная, в которой содержится менее 40 записей, но на нее ссылаются довольно редко.

Вот что происходит: новая таблица создается успешно, но при добавлении ограничения FK она «думает» оочень долго и увеличивает нагрузку на процессор.Использование памяти увеличивается, сервер начинает пейджинг как сумасшедший и перестает отвечать на запросы (время ожидания соединения).Отмена запроса не помогает.Единственное, что работает, это перезагрузка сервера, что очень дорого.

Вот скрипт, который я пытаюсь запустить.Я надеюсь, что гуру SQL-сервера могут помочь.Thx!

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.К сожалению, оба из них были запущены вместе, поэтому я не могу сказать, какая из них вызвала.

РЕДАКТИРОВАТЬ: Как только БД переходит в режим «мышления», можно восстановить его, переключивэто в одиночный режим, а затем обратно в многопользовательский режим.Это намного лучше, чем перезагрузка сервера, но все же недопустимо.

Ответы [ 4 ]

4 голосов
/ 06 декабря 2010

Случайная мысль: у вас есть открытая транзакция?

Для ALTER TABLE потребуется эксклюзивный доступ (как и для большинства DDL), и может случиться так, что он заблокирован блокировкой схемы, которая, в свою очередь, заблокирует ReferenceTableчто, в свою очередь, заблокирует другие запросы ...

0 голосов
/ 28 января 2011

Горстка вещей для изучения - не решения, но они могут привести к чему-то.

Определены ли триггеры?

Используется или используется база данных во время создания новой таблицы, или она простаивает?

Делает ли что-нибудь (во время развертывания или иным образом) UPDATE Column1ID в справочной таблице или удаляет строки в этой таблице?

Есть ли первичный ключ или ограничение уникальности для Column1ID в справочной таблице? (У вас его нет в списке, но я бы подумал, что SQL сразу выйдет из строя, если его не будет.)

0 голосов
/ 28 января 2011

Если эта проблема воспроизводима, я бы предложил вам открыть службу поддержки Microsoft. Может быть, это ошибка, и вы попали в нее. Если выяснится, что это известная проблема, они возместят вам плату за открытие дела.

0 голосов
/ 24 января 2011

Я бы предложил запускать каждый пакет запросов изолированно.

Сначала создайте таблицу и посмотрите, удастся ли это.

Затем попробуйте добавить ограничение внешнего ключа самостоятельно, используя WITH NOCHECK вместо WITH CHECK.WITH NOCHECK будет подавлять любую проверку содержимого в MyNewTable.Column1ID по сравнению со значениями в столбце ссылочной таблицы во время создания ограничения.Если MyNewTable пусто или имеет несколько строк, я не думаю, что это окажет большое влияние, но я столкнулся с такими симптомами, как вы описали, за исключением того, что в таблице, получающей новое ограничение, содержались миллионы строк.

Наконец, запустите ваш последний пакет, чтобы попробовать установить WITH CHECK в вашем новом ограничении.Если это не помогло, вам может потребоваться оставить новый набор FK WITH NOCHECK, однако это не рекомендуется, поскольку ограничения, определенные WITH NOCHECK, игнорируются оптимизатором запросов до тех пор, пока они не будут установлены обратно на WITH CHECK.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...