Ласкаво просимо до dev.net.ua Увійти | Приєднатися | Допомога
«Покрывающие» индексы и SQL Server 2005

Ни для кого не секрет, что индексы могу существенно ускорить выполнение запросов. И если мы часто используем запрос с условием WHERE my_filed=@my_value, то имеет смысл создать индекс по полю my_field. Но индексы бывают разные и иногда их можно использовать для ускорения запросов, даже если поле не входит в условие фильтрации.

Рассмотрим следующий запрос к базе данных AdventureWorks (это стандартная база данных пример в поставке SQL Server 2005):

SELECT DueDate, ShipDate FROM Sales.SalesOrderHeader WHERE OrderDate='2001-07-01'

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

, а оценочная стоимость запроса 0,55.

Добавим индекс:

create index IDX_OrderDeatils on Sales.SalesOrderHeader(OrderDate)

и повторим запрос. План показан ниже, а оценочная стоимость 0,13:

В это случае поиск нужной записи занимает 2% времени, а 97% занимает извлечение данных (полей DueDate, ShipDate) из таблицы.

Что можно сделать в качестве альтернативы?

Можно создать так назывемые покрывающий (covered) индекс:

create index IDX_OrderDeatils on Sales.SalesOrderHeader(OrderDate, DueDate, ShipDate)

план запроса показан ниже, а оценочная стоимость 0,0033

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

Выигрыш можно получить даже если не использовать WHERE часть. Для запроса:

SELECT DueDate, ShipDate FROM Sales.SalesOrderHeader

Мы будем сканировать только маленький индекс, а не всю таблицу (оценка 0,13 против 0,55):

Какие недостатки у этого подхода:

  • Увеличается размер индекса. И мы можем уперется в 900б органичение на длину ключа
  • При каждом изменении полей DueDate, ShipDate возможна существенная перестройка индекса. И выигрыш в выполнении SELECT, может оказатся незаметным на фоне замедления операций обновления.
  • Мы не можем таким образом ускорить работу с полями для которых нельзя строить индекс, например, nvarcahr(,ax)

В SQL Server 2005, есть одно маленькое, но очень приятное расширение – ключевое слово INCLUDE. В этом случае создание индекса будет выглядеть следующим образом:

create index IDX_OrderDeatils on Sales.SalesOrderHeader(OrderDate) include( DueDate, ShipDate)

При этом план запроса будет таким же как и для простого покрывающего :

  • Поля DueDate и ShipDate будут включатся только на самом последнем уровне индекса, что уменьшает его размер. Что приводит к повышению скорости чтения и модицикации.
  • Можно включать поля любого типа (даже те для которых нельзя использовать индексы, в том числе nvarchar(max) и xml) и любой длины (больше нет ограничения на 900б)
Posted: Thursday, May 10, 2007 2:31 PM від kosinsky
Помічено як: , ,

Коментарі

Немає коментарів

Анонімні коментарі деактивовані. Увійдіть або Зареєструйтесь щоб мати доступ до ресурсів Спільноти.