Должен ли я использовать много индексов с одним полем вместо конкретных индексов с несколькими столбцами?


35

Этот вопрос касается эффективности техники индексации SQL Server. Я думаю, что это известно как "пересечение индекса".

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

В таблице много столбцов с возможностью поиска. Разработчики создали индекс по одному столбцу для КАЖДОГО из доступных для поиска столбцов. Теория заключалась в том, что SQL Server сможет комбинировать (пересекать) каждый из этих индексов для эффективного доступа к таблице в большинстве случаев. Вот упрощенный пример (в реальной таблице больше полей):

CREATE TABLE [dbo].[FatTable](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [col1] [nchar](12) NOT NULL,
    [col2] [int] NOT NULL,
    [col3] [varchar](2000) NOT NULL, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

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


У @brentozar есть хорошее видео об индексах, которые стоит посмотреть: brentozar.com/sql-server-training-videos/…
DForck42

Ответы:


38

То, что вам нужно, это покрытие индексов, т.е. индексы, которые могут удовлетворить запрос самостоятельно. Но у «покрывающего» индекса есть одна проблема: он покрывает определенный запрос . Таким образом, чтобы разработать хорошую стратегию индексирования, вам необходимо понять свою рабочую нагрузку: какие запросы попадают в базу данных, какие критичны, а какие нет, как часто выполняется каждый тип запроса и т. Д. И т. Д. сбалансируйте это с затратами на запись и обновление каждого индекса, и у вас есть стратегия индексирования. Если это звучит сложно, это потому, что это сложно.

Однако вы можете применить некоторые правила. MSDN достаточно хорошо охватывает основы:

Существует также множество статей, представленных сообществом, например. Запись веб-трансляции - DBA Darwin Awards: Index Edition .

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


Спасибо, Ремус. Меня интересует относительное преимущество создания целевых многостолбцовых индексов (и включающих в себя) по сравнению с использованием отдельных индексов. Если это «работает достаточно хорошо», то это может быть хорошо. (Выкинет индексы по полям с низкой селективностью). Этот метод должен помочь, когда у нас нет доступа к производственной базе данных, и мы не можем ориентировать наши индексы на фактическое использование.
RaoulRubin
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.