Как не дать фильтру заставить запрос работать намного медленнее - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть следующий фрагмент кода, который выполняется быстро (<1 с): </p>

SELECT
    [Policy].[Value] AS [PolicyId]
   ,[Person].[Value] AS [PersonId]
   ,[Person].[Index] AS [PersonIndex]
FROM
    [dbo].[View] AS [Policy]
    INNER JOIN [dbo].[ViewPerson] AS [Person] WITH(INDEX([Index])) ON ([Policy].[CollectionId] = [Person].[CollectionId] 
AND [Person].[Name] = 'PersonId' AND [Policy].[Name] = 'PolicyId')
WHERE
    [Policy].[CollectionId] = 10003
    -- AND [Policy].[Value] = [Person].[Value]

Это вернет 2 строки из моей базы данных. Когда я закомментирую последнюю строку, чтобы применить более сильный фильтр, она возвращает только 1 строку из моей базы данных, но для ее выполнения потребуется гораздо больше времени (~ 20 с).

Есть ли способ сократить время, которое занимает этот запросработать, когда к нему применен фильтр? В идеале я бы хотел, чтобы он работал на той же скорости, что и оригинал.

1 Ответ

1 голос
/ 07 ноября 2019

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

Во-вторых, вам уже сказали, что план выполнения - это лучшее место для начала. Поскольку мы не видим каких-либо подробностей, следующее является простым предположением:

Если я получу это правильно, ваш запрос будет использовать CollectionId для фильтрации по одному заданному идентификатору (только очень мало строк политики). Для этих строк JOIN на VIEW (мы не знаем, что за этим стоит!) Пытается связать отдельные строки.

Фильтр должен работать с очень сокращенным набором.

ВашНаблюдения позволяют предположить, что вторая строка в WHERE имеет дело с гораздо большим множеством. Я почти уверен, что фильтр для CollectionId=10003 вытягивает после другого фильтра ... План выполнения покажет детали ...

Что вы можете сделать:

  • Уберите индексную подсказку
  • Попробуйте добавить вторую строку в WHERE с AND в ON -пункте JOIN.

Нечто подобное:

SELECT
    [Policy].[Value] AS [PolicyId]
   ,[Person].[Value] AS [PersonId]
   ,[Person].[Index] AS [PersonIndex]
FROM
    [dbo].[View] AS [Policy]
    INNER JOIN [dbo].[ViewPerson] AS [Person]  ON ([Policy].[CollectionId] = [Person].[CollectionId] 
                                               AND [Person].[Name] = 'PersonId' 
                                               AND [Policy].[Name] = 'PolicyId'
                                               AND [Policy].[Value] = [Person].[Value])
WHERE
    [Policy].[CollectionId] = 10003;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...