Добавление ограничения внешнего ключа сосет память и вызывает пейджинг

StackOverflow https://stackoverflow.com/questions/4369628

  •  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 будет сбежать прямо, если бы ни был отсутствует.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top