Каковы лучшие практики для создания индексов для нескольких битовых столбцов? - PullRequest
1 голос
/ 18 марта 2009

Добрый день,

В SQL Server 2005 у меня есть таблица с многочисленными столбцами, включая несколько логических (битовых) столбцов. Например, Таблица «Персона» имеет идентификатор столбцов и столбцы HasItem1, HasItem2, HasItem3, HasItem4. Эта таблица довольно большая, поэтому я хотел бы создать индексы, чтобы получить более быстрые результаты поиска.

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

Кстати, уже есть кластерный индекс, который я не могу удалить.

Ответы [ 6 ]

2 голосов
/ 18 марта 2009

Я не знаю многих особенностей сервера SQL, но в целом индексация столбца, содержащего неуникальные данные, не очень эффективна. В некоторых системах СУБД оптимизатор будет игнорировать индексы, которые в любом случае являются уникальными менее чем на определенный процент, поэтому индекс может даже не существовать.

Использование составного индекса или индекса из нескольких столбцов может помочь, но только в особых случаях, когда ограничения фильтра находятся в том же порядке, в котором был построен индекс. Если индекс включает в себя «field1, field2» и вы ищете 'field2, field1' или некоторая другая комбинация, индекс не может быть использован. Вы можете добавить индекс для каждого конкретного поискового случая, который вы хотите оптимизировать, и это все, что я могу придумать. И в случае, если ваши данные не очень уникальны, даже после рассмотрения всех битовых полей, индекс может быть проигнорирован в любом случае.

Например, если у вас есть 3-битные поля, вы только сегментируете свои данные на 8 отдельных групп. Если у вас есть разумное количество строк в таблице, сегментирование по 8 не будет очень эффективным.

2 голосов
/ 18 марта 2009

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

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

Если бы вы создавали составной индекс для битовых полей, это помогло бы, но только если бы были указаны составные поля в начале индекса. Если вы не включите 1-е значение в составной индекс, индекс, вероятно, вообще не будет использоваться.

Если в качестве примера бита использовалась в 90% ваших запросов, а биты - в 70%, а биты b и c - в 20%, то составной индекс (bita, bitd, bitb, bitc), вероятно, даст некоторое преимущество, но По крайней мере, для 10% ваших запросов и, возможно, даже для 40% индекс, скорее всего, не будет использоваться.

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

0 голосов
/ 23 марта 2009

Скорее всего, для SQL будет проще запрашивать большую таблицу с помощью person_id и item_id и BitValue, чем для поиска в одной таблице с Item1, Item2, ... Item N .

0 голосов
/ 19 марта 2009

Вы должны пересмотреть дизайн вашей базы данных. Вместо того, чтобы иметь таблицу с полями от HasItem1 до HasItem #, вы должны создать сущность моста и главную таблицу элементов, если у вас ее нет. Мостовой объект (таблица), person_items, будет иметь (минимум) два поля: person_id and item_ id.

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

0 голосов
/ 18 марта 2009

Как насчет использования контрольной суммы?

Добавьте поле int с именем mysum в вашу таблицу и выполните это

UPDATE checksumtest SET mysum = CHECKSUM(hasitem1,hasitem2,hasitem3,hasitem4) 

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

Выполните те же вычисления контрольной суммы в поисковом запросе и сопоставьте их с mysum.

Это может ускорить процесс.

0 голосов
/ 18 марта 2009

Не знаю насчет 2005 года, но в SQL Server 2000 (из электронной книги): "Столбцы типа bit не могут иметь индексы на них."

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