Добавление ограничения внешнего ключа сосет память и вызывает пейджинг
-
09-10-2019 - |
Вопрос
У меня много вопросов, добавляющих простое ограничение внешнего ключа на вновь созданную пустую таблицу. Эталонная таблица - это крошечный с менее чем 40 записями, но он немного ссылается.
Вот что происходит: новая таблица создается успешно, но при добавлении ограничений FK он «думает» для очень долгого времени и увеличивает нагрузку на ЦП. Использование памяти увеличивается, сервер начинает пейджинг как сумасшедший и становится не отвечает (время подключения). Отмена запроса не помогает. Единственное, что работает, перезагружается сервер, который очень дорого.
Вот сценарий, который я пытаюсь бежать. Я надеюсь, что SQL Server Guurus может помочь. Спасибо!
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
Column1ID многое касается других таблиц (FK). ExternalColumnID - это FK к другому столу. Проблема происходит во время одного из решающих вызовов таблицы. К сожалению, оба из них были бежать вместе, поэтому я не могу сказать, какой из них это вызвало.
Редактировать: После того, как DB переходит в режим «мышления», можно вернуть его резервным копированию, переключая его в один режим, а затем обратно в Multi пользовательский режим. Это намного лучше, чем перезагрузка сервера, но все еще недопустимо.
Решение
Случайная мысль: у вас есть какая-либо транзакция?
Альтер-таблица потребует эксклюзивного доступа (как и большинство DDL), и может быть, что он заблокирован блокировкой схемы, что, в свою очередь, будет блокировать ссылку на ссылку, что, в свою очередь, заблокирует другие запросы ...
Другие советы
Я бы предложил запустить каждую партию запроса в изоляции.
Во-первых, создайте таблицу и посмотрите, если это удается.
Далее, попробуйте добавить ограничение ключей иностранного ключа самостоятельно, используя WITH NOCHECK
вместо WITH CHECK
. WITH NOCHECK
подавляет любую проверку содержимого в MyNewTable.Column1ID
против значений в столбце ссылки, при этом создается ограничение. Если MyNewTable
Пустой или имеет несколько строк, я бы не подумал, что это будет иметь много эффекта, но я столкнулся с симптомами, как вы описываете - за исключением того, что таблица, заставляя новое ограничение, имело миллионы строк в нем.
Наконец, запустите свою последнюю партию, чтобы попробовать настроить WITH CHECK
на вашем новом ограничении. Если это болота, вам может просто покинуть новый набор FK WITH NOCHECK
, Однако, однако, что не рекомендуется, поскольку ограничения определены WITH NOCHECK
игнорируются оптимизатором запросов, пока они не будут отправлены в WITH CHECK
.
Если этот вопрос воспроизводится, я бы предложил вам открыть корпус поддержки Microsoft. Может быть, это ошибка, и вы его бьете. Если он обнаружил, что это известная проблема, которую они вернут вам обвинения за открытие дела.
Горсть вещей, чтобы посмотреть - не решения, но они могут привести к чему-то.
Есть ли определены триггеры?
База данных используется или доступна в то время, когда вы создаете новую таблицу, или это простаивает?
Делает что-нибудь (во время развертывания или иначе) обновить столбец1ID в эталонной таблице или удалить строки в этой таблице?
Есть ли первичный ключ или уникальное ограничение на столбец 1 в эталонной таблице? (У вас нет одного перечисленного, но я бы подумал, что SQL будет сбежать прямо, если бы ни был отсутствует.)