Во время оптимизации запросов я обнаружил странное поведение сервера 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:
для выбора 18 лучших:
еще один сбивающий с толку факт заключается в том, что для запроса select top 19 иногда используется индексированное представление, а иногда нет.
FROM
? Если да, то меняет ли что-нибудь добавление подсказкиWITH (NOEXPAND)
? - person Damien_The_Unbeliever   schedule 18.11.2011DBCC FREEPROCCACHE; DBCC FREESYSTEMCACHE('ALL')
между запросами, чтобы гарантировать честный тест? - person MicSim   schedule 18.11.2011