Выберите топ-10... и выберите верхнюю 30, следуя за другим планом выполнения

Во время оптимизации запроса я обнаружил странное поведение 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

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

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

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

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