Оптимизируются ли представления, когда я добавляю к ним предложение WHERE?

28

Имеет ли значение, если вы фильтруете представление внутри или снаружи представления?

Например, есть ли разница между этими двумя запросами?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Или

SELECT Id
FROM MyView
WHERE SomeColumn = 1

И MyViewопределяется как

SELECT Id, SomeColumn
FROM MyTable

И отличается ли ответ, если исходная таблица расположена на связанном сервере?

Я спрашиваю, потому что я должен дважды запросить большую таблицу (44 миллиона строк) со связанного сервера, и получить совокупность результатов. Я хочу знать, должен ли я создать два представления для доступа к данным, по одному для каждого запроса, или мне удастся выбрать одно представление и WHEREпредложение.

Рейчел
источник
1
зачем вообще использовать представление, если в нем только одна таблица?
HLGEM
3
@ HLGEM безопасность?
JNK
2
@HLGEM Представление фактически содержит несколько запросов к нескольким базам данных на разных серверах и объединяет их все с помощью a UNION ALL. Гораздо проще использовать View, чем переписывать запрос UNION каждый раз, когда мне нужны данные.
Рэйчел
также см. stackoverflow.com/a/6654525/27535
gbn
1
@datagod Я буду помнить об этом, спасибо :) В этом случае есть довольно маленькое приложение, которое собирает данные с нескольких серверов, выполняет некоторые вычисления и выдает кучу отчетов. У него есть собственная база данных, потому что некоторые расчеты довольно ресурсоемки, и я хотел отделить их от всего остального.
Рэйчел

Ответы:

12

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

Теперь, в зависимости от типа данных и избирательности MyColumn, если вы хотите создать отфильтрованный индекс для базовой таблицы (при переходе на SQL Server 2008+), вы можете получить более высокую производительность, но это снова не изменится через представление или без.

Аарон Бертран
источник
3
Как насчет этого вопроса , который спрашивает, почему запрос с whereпредложением вне представления занимает намного больше времени, чем когда он помещается в представление?
Рэйчел
1
Если представления не для производительности, они просто для структуры?
profimedica
1
Индексированные представления @profimedica могут создаваться по соображениям производительности (например, для хранения промежуточных результатов, таких как агрегаты, вместо их вычисления во время выполнения). Если представление не материализовано, это может быть по ряду причин: СУХОЙ (общее объединение или фильтр, выполняемый во многих различных запросах), безопасность, запутывание, упрощение схемы.
Аарон Бертран
5

Вот только быстрый пример, показывающий, что не должно быть никакой разницы. База данных является AdventureWorksбазой данных.

Два вида определения:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

Здесь будет первый запрос с WHEREпредложением, включенным в определение представления:

select *
from person.vContactWhere

Вот план выполнения:

введите описание изображения здесь

И второй запрос, с WHEREпредложением не в определении представления, а в SELECTзапросе:

select *
from person.vContactNoWhere
where ContactID = 24

Вот этот план выполнения:

введите описание изображения здесь

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

Томас Стрингер
источник
1
Как насчет этого вопроса , который спрашивает, почему запрос с whereпредложением вне представления занимает намного больше времени, чем когда он помещается в представление?
Рэйчел
1
@Rachel Я думаю, что Гбн довольно хорошо объяснил это в своем посте и в статье, на которую он указал. Я не знаю, как еще это выразить.
Томас Стрингер
Я связал это, потому что в этом случае планы выполнения не были одинаковыми, что отличается от того, что говорит ваш ответ.
Рэйчел
1
@Rachel Проблема в этом примере - отсутствующее правило преобразования . Это относится не только к представлениям, но также к CTE и другим табличным выражениям. В общем случае недопустимо помещать предикат в табличные выражения, содержащие функции ранжирования, поскольку это изменит результат. Причина, по которой он действителен в этом случае, заключается в том, что Whereпредложение соответствует PARTITION BY. В SQL Server 2008, похоже, есть новое правило SelOnSeqPrjдля распознавания этого конкретного случая.
Мартин Смит
2

Исходя из того, что я читаю , SQL будет использовать стандартное представление, например подзапрос, при определении плана выполнения.

Итак, используя мой пример запроса,

SELECT Id
FROM MyView
WHERE SomeColumn = 1

где MyViewопределяется как

SELECT Id, SomeColumn
FROM MyTable

он должен генерировать тот же план выполнения, что и

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

но этот план выполнения может отличаться от того, что будет сгенерировано с

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Я не уверен, что этот ответ будет таким же для индексированных представлений

Рейчел
источник
Я не думаю, что это явная замена текста.
Аарон Бертран
@AaronBertrand Вы можете быть правы. Я, честно говоря, понятия не имею ... Я учусь на ходу :) Это предположение было основано на других вещах, которые я читал о том, как представления похожи на макросы. Я немного отредактировал вопрос, чтобы указать, что я имею в виду стандартные, а не индексированные представления.
Рэйчел
@Rachel - Замена происходит с алгебраизированным деревом, а не на текстовом уровне.
Мартин Смит
@MartinSmith Hrrmm это не то, что я сказал? Что планы выполнения должны быть одинаковыми, а текст не будет таким же? Я не уверен, что понимаю «алгебраическое дерево»
Рэйчел
Это было просто в ответ на ваш комментарий к самому Q, который говорит, что он «вставляет текст представления в ваш запрос» и комментарий Аарона выше. Некоторая информация об этапах разбора / компиляции здесь . На самом деле в вашем ответе также упоминается подстановка текста. Стоит ли делать это различие. Не уверена! Но я думаю, это объясняет, почему sp_refreshviewэто необходимо, а концепция замены текста - нет.
Мартин Смит