выберите топ 10 ... и выберите топ 30 следует другой план выполнения - PullRequest
10 голосов
/ 17 ноября 2011

Во время оптимизации запросов я обнаружил странное поведение сервера sql (Sql Server 2008 R2 Enterprise). Я создал несколько индексов для таблиц, а также несколько индексированных представлений. У меня есть два запроса, например:

select top 10 N0."Oid",N1."ObjectType",N1."OptimisticLockField" from ((("dbo"."Issue" N0
 inner join "dbo"."Article" N1 on (N0."Oid" = N1."Oid"))
 inner join "dbo"."ProductLink" N2 on (N1."ProductLink" = N2."Oid"))
 inner join "dbo"."Technology" N3 on (N2."Technology" = N3."Oid"))
where (N1."GCRecord" is null and (N0."IsPrivate" = 0) and ((N0."HasMarkedAnswers" = 0) or N0."HasMarkedAnswers" is null) and (N3."Name" = N'Discussions'))
order by N1."ModifiedOn" desc

и

select top 30 N0."Oid",N1."ObjectType",N1."OptimisticLockField" from ((("dbo"."Issue" N0
 inner join "dbo"."Article" N1 on (N0."Oid" = N1."Oid"))
 inner join "dbo"."ProductLink" N2 on (N1."ProductLink" = N2."Oid"))
 inner join "dbo"."Technology" N3 on (N2."Technology" = N3."Oid"))
where (N1."GCRecord" is null and (N0."IsPrivate" = 0) and ((N0."HasMarkedAnswers" = 0) or N0."HasMarkedAnswers" is null) and (N3."Name" = N'Discussions'))
order by N1."ModifiedOn" desc

оба запроса одинаковы, за исключением того, что первый начинается с выберите топ 10 , а второй с выберите топ 30 . Оба запроса возвращают одинаковый набор результатов - 6 строк. Но второй запрос в 5 раз быстрее первого! Я посмотрел на реальные планы выполнения для обоих запросов, и, конечно, они отличаются. Второй запрос использует индексированное представление и работает отлично, а первый запрос отказывается его использовать, используя вместо этого индексы для таблиц. Повторюсь - оба запроса одинаковы, к одной и той же таблице, на одном и том же сервере они отличаются только числом в «верхней» части. Я пытался заставить оптимизатор использовать индексированное представление в первом запросе, обновляя статистику, уничтожая используемые им индексы и так далее. Независимо от того, как я пробую реальное выполнение, не используйте индексированное представление для первого запроса и всегда используйте его для второго.

Меня действительно интересуют причины, вызывающие такое поведение. Есть предложения?

Обновление Я не уверен, что это может помочь без описания соответствующих индексов и представления, но это фактические диаграммы плана выполнения: для выбора топ 19: for select top 19:

для выбора топ 18: for select top 18:

Еще один запутанный факт заключается в том, что для запроса select top 19 иногда используется индексированное представление, иногда нет

1 Ответ

1 голос
/ 21 ноября 2011

Единственное, о чем я могу думать, - это, возможно, оптимизатор в первом запросе, заключивший, что заданные критерии недостаточно избирательны для использования «лучшего» плана выполнения.

Если вы все еще исследуете это, посмотрите, если TOP 60, 90, 100, ... создает второй план выполнения и работает хорошо.Вы также можете поработать с ним, чтобы увидеть, какой порог для оптимизатора, чтобы выбрать второй план в этом случае.

Также попробуйте запросы без оператора order by, чтобы увидеть, влияет ли это на выбор плана запроса (проверьте индекс в этом поле и т. Д.)

Помимо этого, вы сказали, что можетене используйте индексные подсказки, так что, возможно, переписать, где вы выбираете вершину X из таблицы Article (N1), с кучей операторов существует в предложении where, чтобы обеспечить лучшую производительность для вас.

...