Соединение один в один Недостаточно быстро в SQL Server

У меня есть наследование TPT в моей модели EF. Где есть абстрактный тип "Мастер", от которого наследуются несколько типов, включая "Порядок". Есть 1700000 заказов, но у мастера есть еще много строк, соответствующих другим типам.

У нас был странный случай, когда выбор 50 заказов выполнялся медленнее, чем выбор тех же 50 заказов, но с некоторыми другими связанными объектами. Отследил до базы данных, где очень простой запрос

select top 50 * from SAM.Master m 
join SAL.[Order] o on o.OrderMasterID = m.MasterID
order by MasterID desc

занимает больше секунды. (Да, в нашем случае, одна секунда на самом деле слишком много). Но это может быть сделано быстрее либо

  1. Удаление order by (примерно в два раза быстрее)
  2. сортировка по возрастанию (кластеризованные индексы по возрастанию и не может быть иначе)
  3. добавление option(loop join) (очень быстро)
  4. используя левое внешнее соединение
  5. Добавление Where FormTypeID = 1 (столбец дискриминатора в главной таблице, который равен 1 для всех заказов) (в два раза быстрее)

на самом деле единственное решение, которое дало тот же результат, это 3 и 5, но 3 невозможно с помощью Entity Framework (мы не можем добавить подсказки к запросам), а 5 недостаточно быстро

Любые предложения с благодарностью.

2 ответа

Решение

Вы можете использовать руководства плана, чтобы получить желаемое поведение. См. Использование подсказок запросов в руководствах по плану для примера. В примере требуется фактический текст оператора (T-SQL, сгенерированный EF), но вы можете обойти необходимость получения оператора EF, используяsp_create_plan_guide_from_handle,

В вашем следующем проекте избегайте использования наследования таблиц классов с базой Master объект, который каждая сущность происходит от...

Если вы хотите форсировать подсказку запроса. Я думаю, что ваш лучший крик - это создать процедуру хранилища и использовать подсказку запроса (подробнее здесь). Или, может быть, вы можете сделать что-то вроде этого:

var items = dc.ExecuteQuery<ToSomeObject>("YourQueryWithHints").ToList();
Другие вопросы по тегам