Является ли представление быстрее, чем простой запрос?

359

Это

select *  from myView

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

select * from ([query to create same resultSet as myView])

?

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

JohnIdol
источник
7
Я не уверен насчет одного представления, но вложенные представления - это полная адская производительность.
Muflix,

Ответы:

680

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

Обновление: по крайней мере три человека проголосовали против меня на этом. При всем уважении, я думаю, что они просто неправы; Из собственной документации Microsoft очень ясно видно, что Views может повысить производительность.

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

Позвольте мне перейти непосредственно к документации:

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

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

Опять документация:

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

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

Обновление 2: ответ подвергся критике на том основании, что именно «индекс» обеспечивает преимущество в производительности, а не «представление». Однако это легко опровергнуть.

Допустим, мы являемся компанией-разработчиком программного обеспечения в маленькой стране; Я буду использовать Литву в качестве примера. Мы продаем программное обеспечение по всему миру и храним наши записи в базе данных SQL Server. Мы очень успешны, и через несколько лет у нас более 1 000 000 записей. Однако нам часто приходится сообщать о продажах для целей налогообложения, и мы находим, что мы продали только 100 копий нашего программного обеспечения в нашей стране. Создав индексированное представление только литовских записей, мы получаем нужные записи в индексированном кэше, как описано в документации MS. Когда мы запустим наши отчеты по продажам в Литве в 2008 году, наш запрос будет искать по индексу с глубиной всего 7 (Log2 (100) с некоторыми неиспользованными листьями). Если бы мы сделали то же самое без ПРОСМОТРА и просто полагаясь на индекс в таблице, нам пришлось бы обходить дерево индексов с глубиной поиска 21!

Ясно, что само представление даст нам преимущество в производительности (в 3 раза) по сравнению с простым использованием только индекса. Я пытался использовать пример из реальной жизни, но вы заметите, что простой список продаж в Литве даст нам еще большее преимущество.

Обратите внимание, что я просто использую прямое b-дерево для моего примера. Хотя я совершенно уверен, что SQL Server использует какой-то вариант b-дерева, я не знаю деталей. Тем не менее, точка имеет место.

Обновление 3: возник вопрос о том, использует ли индексированное представление индекс, размещенный в базовой таблице. То есть, перефразируя: «индексированное представление - это просто эквивалент стандартного индекса, и оно не предлагает ничего нового или уникального для представления». Конечно, если бы это было правдой, то приведенный выше анализ был бы неверным! Позвольте мне привести цитату из документации Microsoft, которая демонстрирует, почему я считаю эту критику недействительной или правдивой:

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

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

Mark Brittingham
источник
29
Да, индексированные представления могут значительно повысить производительность. Но индексированные представления - это не просто «представления», и, вообще говоря, обычные «представления» не быстрее, чем связанные с ними запросы.
BradC
10
@Charles - не имеет значения, является ли он индексом, достаточно того факта, что представление может использовать индекс, а необработанный запрос - недостаточно
annakata
196
/ аплодируют @Mark за то, что он стоял на своем и рационально спорил об этом
annakata
17
О, чувак, я получил 8 понижений на этом! Я поражен, что люди так быстро понизят голос, не имея хотя бы смелости Чарльза, чтобы аргументировать свою точку зрения.
Марк Бриттингем
8
Поскольку таблица может иметь только один индекс clusterdee, и вы МОЖЕТЕ создать отдельный кластеризованный индекс для представления (поскольку поля в кластеризованном индексе независимо сохраняются на страницах индекса), это чит (work-arounnd?), Который позволяет получить два кластерных индекса на одной таблице.
Чарльз Бретана
51

Вообщем нет. Представления в основном используются для удобства и безопасности, и сами по себе не принесут никакого преимущества в скорости.

Тем не менее, SQL Server 2000 и более поздние версии имеют функцию индексированных представлений, которая может значительно повысить производительность, с несколькими оговорками:

  1. Не каждое представление может быть преобразовано в индексированное представление; они должны следовать определенным набором руководящих принципов , которые (наряду с другими ограничениями) означает , что вы не можете включать в себя общие элементы запроса , такие как COUNT, MIN, MAXили TOP.
  2. Индексированные представления используют физическое пространство в базе данных, так же как индексы в таблице.

В этой статье описываются дополнительные преимущества и ограничения индексированных представлений :

Ты можешь…

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

Вы не можете ...

  • Определение представления не может ссылаться на другие представления или таблицы в других базах данных.
  • Он не может содержать COUNT, MIN, MAX, TOP, внешние объединения или несколько других ключевых слов или элементов.
  • Вы не можете изменить базовые таблицы и столбцы. Представление создается с опцией WITH SCHEMABINDING.
  • Вы не всегда можете предсказать, что будет делать оптимизатор запросов. Если вы используете Enterprise Edition, он автоматически будет рассматривать уникальный кластеризованный индекс в качестве опции для запроса - но если он найдет «лучший» индекс, он будет использован. Вы можете заставить оптимизатор использовать индекс через подсказку WITH NOEXPAND - но будьте осторожны при использовании любой подсказки.
BradC
источник
3
совершенно не согласен ... чтение из представления позволяет переписать SQL ... и, как правило, читать быстрее из представления (чем из дампа представления).
Аарон Кемпф
@AaronKempf, я хотел бы увидеть какую-то ссылку на это, это был не мой опыт. Когда я ищу «просмотр переписанного SQL», все результаты, которые я получаю, относятся к Oracle, а не к серверу SQL, например, docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
BradC
Вчера я просто делал некоторые тесты, я был ошеломлен .. в основном, если я получаю дамп из представления (в таблицу), любой запрос, который я выполняю, является МЕДЛЕННЫМ .., потому что большинство запросов проходит через представление как масло и переписывается оптимизатором запросов .. По крайней мере, это то, что я предполагаю. Я постараюсь написать запись в блоге об этом в ближайшее время, сравнительный анализ был довольно увлекательным занятием. В основном, представления помогают значительно повысить производительность.
Аарон Кемпф
@AaronKempf Не уверен, что это даже тот же сценарий, что и в исходном вопросе (речь идет о запросе против размещения идентичного запроса в представлении). Во всяком случае, я не могу понять, как материализация представления в таблицу сделает его МЕДЛЕННЫМ (это именно то, что делает индексированное представление), если ваша новая таблица не имеет хороших индексов.
BradC
1
Brad; Я написал очень плохую запись в блоге о том, как представления экономят мне 99% моей производительности в этой ситуации. Я планирую написать пару других статей, но я знаю, что мне нужно добавить ТОННУ более подробно. Вы не возражаете взглянуть на это и сказать мне, что вы думаете о моем описании? Я знаю, что это не будет иметь больше смысла (пока я не получу 2-3 других статьи) .. но я безумно влюблен в представления, и я был в течение долгого времени! accessadp.com/2013/01/22/do-views-increase-performance
Аарон Кемпф
14

По крайней мере, в SQL Server планы запросов хранятся в кэше планов как для представлений, так и для обычных запросов SQL на основе параметров запроса / представления. Для обоих они удаляются из кэша, если они не использовались в течение достаточно длительного периода, и для некоторого другого вновь отправленного запроса требуется место. После чего, если выдается тот же запрос, он перекомпилируется и план помещается обратно в кеш. Так что нет, разницы нет, учитывая, что вы повторно используете один и тот же SQL-запрос и одно и то же представление с одинаковой частотой.

Очевидно, что в общем случае представление по самой своей природе (то, что кто-то думал, что его следует использовать достаточно часто, чтобы превратить его в представление), как правило, более «повторно используется», чем любой произвольный оператор SQL.

Чарльз Бретана
источник
14

РЕДАКТИРОВАТЬ: Я был неправ, и вы должны увидеть ответ Маркса выше.

Я не могу говорить по опыту работы с SQL Server , но для большинства баз данных ответ будет отрицательным. Единственное потенциальное преимущество, которое вы получаете с точки зрения производительности, - это то, что оно может потенциально создать некоторые пути доступа на основе запроса. Но главная причина использования представления - это упрощение запроса или стандартизация способа доступа к некоторым данным в таблице. Вообще говоря, вы не получите выигрыша в производительности. Возможно, я ошибаюсь.

Я бы придумал более сложный пример и сам бы его посмотрел.

Райан Гилл
источник
1
Еще одна причина для представлений заключается в содействии контролю доступа в ролевых моделях
annakata
1
Вы ошибаетесь в улучшении производительности. Я не объяснил достаточно, чтобы убедить некоторых людей в моем первоначальном комментарии, но у MS есть явная документация о том, как использовать представления для повышения производительности. Смотрите мой (в настоящее время сильно отрицательный) ответ ниже.
Марк Бриттингем
7

Это может быть быстрее, если вы создадите материализованное представление ( с привязкой схемы ). Нематериализованные представления выполняются так же, как и обычный запрос.

Otávio Décio
источник
привязка схемы имеет мало общего с производительностью, она связывает схему представления с базовой таблицей, поэтому она остается синхронизированной и является предварительным требованием для индексированных представлений.
Сэм Шафран
5

Насколько я понимаю, некоторое время назад представление было бы быстрее, потому что SQL Server мог сохранить план выполнения, а затем просто использовать его вместо того, чтобы пытаться понять его на лету. Я думаю, что прирост производительности в настоящее время, вероятно, не так велик, как это было раньше, но я должен был бы предположить, что было бы небольшое улучшение, чтобы использовать представление.

Э.Дж. Бреннан
источник
Это было мое понимание: имел значение, больше нет
annakata
Не с точки зрения производительности, а как средство ограничения доступа. Но это была бы другая тема. ;)
AnonJr
о, конечно, есть много веских причин для использования представлений, а не для использования необработанных запросов: P
annakata
4

Определенно, представление лучше, чем вложенный запрос для SQL Server. Не зная точно, почему это лучше (пока я не прочитал пост Марка Бриттингема), я провел несколько тестов и испытал почти шокирующее повышение производительности при использовании представления вместо вложенного запроса. После выполнения каждой версии запроса несколько сотен раз подряд просмотр версии запроса выполнялся наполовину. Я бы сказал, что для меня достаточно доказательств.


источник
Спасибо Джордан ... рад слышать, что вся эта теория работает в реальном мире.
Марк Бриттингем
У меня есть опыт работы с вложенным представлением (view in view), и производительность была очень плохой. Когда все представления были переписаны для подвыборов, производительность была во много раз выше, поэтому, возможно, есть место для серьезного тестирования.
Muflix,
2

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

Тони Эндрюс
источник
Если представление представляет собой небольшой набор полей и эти поля затем покрыты индексом, достаточно ли у SQL Server достаточно умного, чтобы использовать этот покрывающий индекс при выполнении второй формы запроса?
AnthonyWJones
1

Все зависит от ситуации. Индексированные представления MS SQL выполняются быстрее, чем обычные представления или запросы, но индексированные представления нельзя использовать в зеркальной среде базы данных (MS SQL).

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

Так что все зависит от ситуации.

DasBoot
источник
0

В этом нет никакой практической разницы, и если вы прочитаете BOL, вы обнаружите, что ваш обычный SQL SELECT * FROM X использует преимущества кэширования плана и т. Д.

keithwarren7
источник
0

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

JosephStyons
источник
0

Цель представления - использовать запрос снова и снова. Для этого SQL Server, Oracle и т. Д. Обычно предоставляют «кэшированную» или «скомпилированную» версию вашего представления, что повышает его производительность. В целом, это должно работать лучше, чем «простой» запрос, хотя, если запрос действительно очень прост, преимущества могут быть незначительными.

Теперь, если вы делаете сложный запрос, создайте представление.


источник
0

На мой взгляд, использование представления немного быстрее, чем обычный запрос. Моя хранимая процедура занимала около 25 минут (работа с другими большими наборами записей и несколькими объединениями), и после использования представления (некластеризованного) производительность была немного выше, но не существенной. Мне пришлось использовать некоторые другие методы / методы оптимизации запросов, чтобы сделать это кардинальным изменением.

КТА
источник
Как мы пишем / проектируем запрос, очень важно.
КТА
Я обнаружил, что использование CTE для ограничения данных, возвращаемых из таблицы, а затем выполнение всей работы / объединений и т. Д. Из CTE во многих случаях значительно улучшило производительность
MattE
0

Выбор из представления или из таблицы не будет иметь особого смысла.

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

Вы даже можете создать индекс по представлениям для более быстрого поиска. http://technet.microsoft.com/en-us/library/cc917715.aspx

Но если вы выполняете поиск как "% ...%", то движок sql не получит выгоды от индексации по текстовому столбцу. Если вы сможете заставить своих пользователей выполнять поиск, например, «...%», это будет быстро

см. ответ на форумах asp: https://forums.asp.net/t/1697933.aspx?Which+is+faster+when+using+SELECT+query+VIEW+or+Table+

Мохамад Реза Шахрестани
источник
0

Несмотря на все ожидания, взгляды в некоторых обстоятельствах намного медленнее.

Я обнаружил это недавно, когда у меня были проблемы с данными, которые были извлечены из Oracle, которые нужно было преобразовать в другой формат. Может быть, 20 тысяч строк. Маленький столик Чтобы сделать это, мы импортировали данные оракула, как я мог, в таблицу, а затем использовали представления для извлечения данных. У нас были вторичные взгляды, основанные на этих взглядах. Возможно 3-4 уровня просмотров.

Один из последних запросов, который извлек, может быть, 200 строк, занял бы более 45 минут! Этот запрос был основан на каскаде взглядов. Может быть, 3-4 уровня в глубину.

Я мог бы взять каждое из рассматриваемых представлений, вставить его sql в один вложенный запрос и выполнить его за пару секунд.

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

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

Таким образом, использование запросов, которые извлекают из представлений, которые извлекают из представлений, намного медленнее, чем вложенных запросов, что для меня не имеет смысла.

Ян
источник
-1

Я натолкнулся на эту ветку и просто хотел поделиться этим постом с Брентом Озаром, чтобы рассмотреть его при использовании групп доступности.

Сообщение об ошибке Brent Ozar

JohnH
источник