Добавление основного ограничения замедляет производительность соединения на MS SQL Server 2016?

#sql #sql-server #tsql

#sql #sql-server #tsql

Вопрос:

Основная проблема: добавление ограничения первичного ключа к двум таблицам приводит к увеличению времени запроса с 1 минуты 30 до 40 минут.

У меня есть две таблицы с ключами идентификации int:

 Addresses 
(
    [ID] [int] NOT NULL,
    ...
)

Routes 
(
    [ID] [int] NOT NULL,
    [OriginAddressID] [int] NOT NULL,
    [DestinationAddressID] [int] NOT NULL,
    ...
)
  

У меня есть представление, которое объединяет адреса и маршруты по их идентификаторам:

 select * 
from Routes 
inner join Addresses Origin on Routes.OriginAddressID = Origin.ID
inner join Addresses Destination on Routes.DestinationAddressID = Destination.ID
  

Когда я запрашиваю все строки из этого объединенного представления, выполнение занимает 1 минуту 30 секунд при удалении ограничения первичного ключа из обеих таблиц.

Когда я добавляю первичный ключ в идентификатор столбца, время выполнения увеличивается до 40 минут.

Обе таблицы содержат 400 000 строк. Я тестировал это несколько раз, результаты всегда одинаковы. Я не знаю, как поступить, поскольку время запроса в 40 минут неприемлемо. Насколько я знаю, первичные ключи не должны снижать производительность запросов?

Комментарии:

1. Каждый раз, когда вам нужна помощь с медленным запросом, пожалуйста, предоставьте план его выполнения, чтобы мы могли видеть, что на самом деле делает движок. Предпочтительно использовать какой-либо сервис, такой как brentozar.com/pastetheplan

2. Похоже, происходит что-то еще. Кроме того, вы не указываете, в какую таблицу вы добавили ограничение первичного ключа.

3. Если вы создаете первичный ключ на Addresses.ID , первое, что я бы также сделал, это создал некластеризованные индексы в столбцах внешнего ключа Routes.OriginAddressID и Routes.DestinationAddressID , которые участвуют в этих соединениях ….

4. «Когда я добавляю первичный ключ в идентификатор столбца …» — Какой? Есть два столбца ID .

5. Попробуйте выполнить запрос с одним или несколькими определенными столбцами вместо * , например SELECT Origin.ID FROM ... . Если запрос выполняется быстрее таким образом, это может указывать на то, что использование * нарушает план запроса.