Должен ли я индексировать битовое поле в SQL Server? - PullRequest
92 голосов
/ 23 октября 2008

Я помню, как однажды читал, что индексирование поля с низким количеством элементов (малое количество различных значений) на самом деле не стоит делать. Я признаю, что недостаточно знаю, как работают индексы, чтобы понять, почему это так.

Так что, если у меня есть таблица с 100 миллионами строк, и я выбираю записи, где битовое поле равно 1? И скажем, что в любой момент времени существует только несколько записей, где битовое поле равно 1 (в отличие от 0). Стоит ли индексировать это битовое поле или нет? Почему?

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

Ответы [ 19 ]

2 голосов
/ 23 октября 2008

Если вы хотите знать, имеет ли индекс желаемые эффекты: протестируйте и попробуйте снова.

Как правило, вам не нужен индекс, который недостаточно сужает вашу таблицу из-за затрат на поддержание индекса. (стоимость> прибыль). Но если индекс в вашем случае сократит таблицу пополам, вы можете что-то получить, но положите ее на стол. Все зависит от точного размера / структуры вашей таблицы и от того, как вы ее используете (количество операций чтения / записи).

1 голос
/ 24 октября 2008

Вы не можете проиндексировать битовое поле в SQL Server 2000, как указывалось в электронной документации в то время:

бит

Целочисленный тип данных 1, 0 или NULL.

Примечания

Столбцы типа бит не могут есть индексы на них.

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

Примечание : Enterprise Manager не позволит вам создать индекс для битового столбца. Если вы хотите, вы все равно можете вручную создать индекс для битового столбца:

CREATE INDEX IX_Users_IsActiveUsername ON Users
(
   IsActive,
   Username
)

Но SQL Server 2000 на самом деле не будет использовать такой индекс - выполнение запроса, где индекс будет идеальным кандидатом, например:

.
SELECT TOP 1 Username 
FROM Users
WHERE IsActive = 0

Вместо этого SQL Server 2000 будет выполнять сканирование таблицы, действуя так, как будто индекс даже не существует. Если вы измените столбец на tinyint, SQL Server 2000 будет выполнять поиск по индексу. Также следующий необработанный запрос:

SELECT TOP 1 * 
FROM Users
WHERE IsActive = 0

Будет выполнен поиск по индексу с последующим поиском по закладке.


SQL Server 2005 имеет ограниченную поддержку индексов для битовых столбцов. Например:

SELECT TOP 1 Username 
FROM Users
WHERE IsActive = 0

вызовет поиск индекса через индекс покрытия. Но непокрытый корпус:

SELECT TOP 1 * 
FROM Users
WHERE IsActive = 0

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

Проверено экспериментально и прямым наблюдением.

1 голос
/ 24 октября 2008

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

1 голос
/ 21 декабря 2011

очень поздний ответ ...

Да, это может быть полезно в соответствии с командой CAT CAT (обновлено, консолидировано)

0 голосов
/ 24 октября 2008

Кардинальность является одним из факторов, а другой - насколько хорошо индекс разделяет ваши данные. Если у вас около половины 1 с половиной 0, то это поможет. (Предполагая, что этот индекс является лучшим путем для выбора, чем какой-либо другой индекс). Тем не менее, как часто вы вставляете и обновляете? Добавление индексов для производительности SELECT также снижает производительность INSERT, UPDATE и DELETE, так что имейте это в виду.

Я бы сказал, если от 1 до 0 (или наоборот) не лучше, чем от 75% до 25%, не беспокойтесь.

0 голосов
/ 10 февраля 2010

Ян Бойд прав, когда говорит, что вы не можете сделать это с помощью Enterprise Manager для SQL 2000 (см. Его примечание относительно его создания с помощью T-SQL.

0 голосов
/ 23 октября 2008

Это обычный запрос? Может быть, это стоит того, чтобы искать «горстку» записей, но в других рядах вам не поможет. Существуют ли другие способы идентификации данных?

0 голосов
/ 01 апреля 2017

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

0 голосов
/ 23 октября 2008

измерьте время отклика до и после и посмотрите, стоит ли оно того; теоретически это должно повысить производительность запросов, использующих индексированные поля, но это действительно зависит от распределения значений true / false и других полей, участвующих в запросах, которые вас беспокоят

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