Таким образом, я пытаюсь понять, как SQL Server использует индексы на таблицах позади представлений. Вот сценарий: Таблица A имеет составной кластерный индекс на полях 1 и 2 и некластеризованный индекс на полях 3 и 4.
Представление A записано против Таблицы A для отфильтровывания дополнительных полей, но поля 1-4 являются частью представления. Таким образом, мы пишем запрос, который соединяет представление с другой таблицей на некластеризованных индексных полях.
Получающийся план запросов совершает нападки, Таблица A со сканированием кластерного индекса (вместо ожидаемого некластеризованного индекса ищут). Однако, если мы заменяем представление в ИЗ пункта с таблицей, план запросов затем поражает некластеризованный индекс, и мы добираемся, индекс ищут, мы ожидали.
Разве механизм SQL не должен использовать индекс на таблице, на которой создается представление? Так как это не делает, почему нет?
Когда вы думаете о нематериализованных представлениях и оптимизации, думайте о них так:
Движок "вырезает и вставляет" текст представления в каждый запрос, который вы выполняете.
Хорошо, это не совсем 100% правда, но это, вероятно, самый полезный способ представить себе, что можно ожидать в плане производительности.
Однако представления могут быть сложными. Люди склонны думать, что если столбец находится в представлении, то это означает что-то значительное, когда речь идет о производительности запроса. На самом деле, если запрос, использующий ваше представление, не включает набор столбцов, его можно "оптимизировать". Так, если вы выберете все столбцы из ваших базовых таблиц в представлении, а затем выберете только один или два столбца при фактическом использовании представления, запрос будет оптимизирован с учетом только этих двух выбранных столбцов.
Другим следствием этого является то, что вы можете использовать представления для очень агрессивного выравнивания структуры таблиц. Допустим, у меня есть следующая схема:
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;
Обратите внимание на LEFT JOIN в определении представления. Если бы вы просто SELECT Name, Price FROM vw_Widgets
, вы бы заметили, что WidgetType даже не был включен в план запроса! Он полностью оптимизирован! Это работает с LEFT JOINS по уникальным столбцам, потому что оптимизатор знает, что поскольку ID WidgetType является UNIQUE, он не создаст никаких дублирующих строк в результате объединения. А поскольку есть FK, вы знаете, что можете оставить соединение как LEFT-соединение, потому что у вас всегда будет соответствующая строка.
Итак, мораль этой истории с представлениями такова: в конце дня важны столбцы, которые вы выбираете, а не столбцы в представлении. Представления не оптимизируются при их создании - они оптимизируются при их использовании.
Ваш вопрос не совсем о представлениях
Ваш вопрос на самом деле более общий - почему вы не можете использовать индекс NC? Я не могу сказать вам точно, потому что не вижу вашей схемы или конкретного запроса, но достаточно сказать, что в определенный момент оптимизатор видит, что стоимость поиска дополнительных полей перевешивает стоимость сканирования таблицы (потому что поиск дорог) и игнорирует ваш некластеризованный индекс.