Как SQL Server обрабатывает индексы в таблице за представлением? - PullRequest
9 голосов
/ 23 июля 2010

Итак, я пытаюсь понять, как SQL Server использует индексы для таблиц за представлениями.Вот сценарий: Таблица A имеет составной кластеризованный индекс для полей 1 и 2 и некластеризованный индекс для полей 3 и 4.

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

Результирующий план запроса обращается к таблице A с сканированием кластеризованного индекса (вместо ожидаемого поиска некластеризованного индекса).Однако, если мы заменим представление в предложении FROM на таблицу, план запроса попадет в некластеризованный индекс, и мы получим ожидаемый индексный поиск.

Разве механизм SQL не должен использовать индекс втаблица, на которой построен вид?Так как это не так, почему бы и нет?

1 Ответ

6 голосов
/ 23 июля 2010

Когда вы думаете о нематериализованных представлениях и оптимизациях - думайте о них так:

Движок "вырезает и вставляет" текст представления в каждый выполняемый вами запрос.

Хорошо, это не совсем на 100% верно, но это, вероятно, самый полезный способ думать о том, чего ожидать с точки зрения производительности.

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

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

Widget
-------
ID (UNIQUE)
Name
Price
WidgetTypeID (FK to WidgetType.ID)

WidgetType
----------
ID (UNIQUE)
Name

vw_Widgets
----------
SELECT w.ID, w.Name, w.Price, w.WidgetTypeID, wt.Name AS TypeName
FROM Widgets w
LEFT JOIN WidgetType wt
   ON wt.ID = w.WidgetTypeID;

Обратите внимание на левое соединение в определении представления.Если бы вы просто SELECT Name, Price FROM vw_Widgets, вы заметили бы, что WidgetType даже не был вовлечен в план запроса!Это полностью оптимизировано!Это работает с LEFT JOINS для уникальных столбцов, потому что оптимизатор знает, что, поскольку идентификатор WidgetType является UNIQUE, он не будет генерировать дублирующиеся строки из соединения.И поскольку есть FK, вы знаете, что можете оставить соединение как левое, потому что у вас всегда будет соответствующая строка.

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

Ваш вопрос на самом деле не касается представлений

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

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