Многие младшие администраторы баз данных/разработчики и студенты не понимают, какой индекс следует создать для настройки производительности запроса. За последние 16 лет работы в качестве база баз данных SQL я провел более 500 собеседований на разных уровнях и видел, что даже очень старший администратор баз данных временами не понимает, какой индекс будет правильно поддерживать мой запрос.

Итак, давайте посмотрим очень краткое и ясное объяснение того, какой индекс улучшит производительность моего запроса и почему:

Мы будем использовать приведенные ниже примеры запросов:

CREATE TABLE [dbo].[Здания](

[Buildingid] [int] NOT NULL,

[BuildingName] [varchar] (50) NULL,

[BuildingLocation] [varchar] (50) NULL,

ГРУППА ПЕРВИЧНОГО КЛЮЧА

(

[Идентификатор здания] ASC

)

)

— ВСТАВЬТЕ НЕСКОЛЬКО ЗАПИСЕЙ

ВСТАВЬТЕ В Здания значения (1, «Эмпайр-Стейт», «Нью-Йорк»)

ВСТАВЬТЕ В Здания значения (2, ‘Building2’, ‘NDLS’)

ВСТАВЬТЕ В Здания значения (3, ‘Building3’, ‘NDLS’)

ВСТАВЬТЕ В Здания значения (4, «Здание 4», «Мумбаи»)

ВСТАВЬТЕ В Здания значения (5, «Здание 5», «Мумбаи»)

ВСТАВЬТЕ В Здания значения (6, «Здание 6», «Мумбаи»)

ВСТАВЬТЕ В Здания значения (7, ‘Building7’, ‘LA’)

ВСТАВЬТЕ В Здания значения (8, ‘Building8’, ‘LA’)

ВСТАВЬТЕ В Здания значения (9, ‘Building9’, ‘LAS’)

ВСТАВИТЬ В Здания (10, Building10, LAS)

— Поиск по кластерному индексу

выберите Buildingid FROM Buildings WHERE Buildingid=1

Как вы можете видеть выше, поскольку у нас есть предложение where в кластеризованном индексе, а SELECT также имеет кластеризованный столбец, произойдет поиск кластеризованного индекса.

— Сканирование кластерного индекса

выберите Buildingid FROM Buildings WHERE BuildingName='Empire State'

Теперь, поскольку предложение where имеет некластеризованный столбец, оптимизатор запросов не может получить данные для BuildingName. Как показано выше, будет просканирован весь кластеризованный индекс. ЗАМЕТЬТЕ, что кластеризованный индекс не содержит ничего, кроме самой таблицы, которая отсортирована по некоторому столбцу, здесь BuildingId.

— Создать вспомогательный индекс

создать индекс IDX_Buildings_BuildingName для Buildings (BuildingName)

— Сканирование преобразуется в некластеризованный поиск по индексу.

выберите Buildingid FROM Buildings WHERE BuildingName='Empire State'

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

— Сканирование или поиск

выберите BuildingLocation FROM Buildings WHERE BuildingName='Empire State'

Приведенный выше запрос даст сканирование кластерного индекса или поиск ключа в зависимости от объема данных. Здесь данных меньше, поэтому оптимизатор решает сделать сканирование. Почему это произошло? Поскольку BuildingLocation не является частью какого-либо индекса. Таким образом, у оптимизатора нет возможности получить эти данные, поэтому он должен выполнить сканирование. Чтобы покончить с этим сканированием, нам нужно создать покрывающий индекс.

— Индекс покрытия

создать индекс IDX_Buildings_BuildingName2 для зданий (BuildingName) INCLUDE (BuildingLocation)

— Идеальный поиск сейчас

выберите BuildingLocation FROM Buildings WHERE BuildingName='Empire State'

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

Теперь нам действительно нужен IDX_Buildings_BuildingName. Не совсем. Разберитесь, почему бы и нет.

Спасибо.