Индексирование SQL - вычисляемый столбец против поля, используемого вычисляемым столбцом - PullRequest
2 голосов
/ 16 декабря 2009

Быстрый вопрос для DBA там:

Допустим, у меня в таблице 2 столбца: IsDeleted (бит) и DeletedDate (дата / время). Таблица содержит около 10 000 000 строк.

IsDeleted - это вычисляемый столбец, который проверяет, имеет ли значение DeletedDate значение NULL; и возвращает 1, если это не так, и 0, если это так.

Запросы к этой таблице в основном будут выполняться в столбце IsDeleted.

Кто-нибудь может дать мне несколько советов о том, где я должен применять свой индекс?

Применение его к полю IsDeleted приводит к появлению множества проблем, связанных с отключением SET QUOTED IDENTIFIER, что не обязательно нарушает условия сделки, но может привести к дополнительной работе.

Могу ли я увидеть какую-либо выгоду, применяя ее к DeletedDate, даже если я не запрашиваю это поле напрямую? Должен ли я просто укусить пулю и добавить ее в IsDeleted? Является ли разница в производительности между этими двумя незначительными?

Еще раз спасибо; и если вы хотите каких-либо разъяснений; оставьте мне комментарий, и я обновлю свой пост.

Ответы [ 5 ]

3 голосов
/ 17 декабря 2009

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

Помещение индекса в DeletedDate, возможно, может помочь с некоторыми запросами, но фильтрация по NULL и «любому значению», вероятно, также не сильно поможет из-за селективности.

Я советую вам прочитать это: Ищите против. Сканирование

1 голос
/ 21 июня 2010

Скажите, что распределение: 98% IsDeleted = 0 2% IsDeleted = 1

Будет ли SQL Server достаточно умен, чтобы хранить в индексе только информацию для записей IsDeleted?

1 голос
/ 17 декабря 2009

Невозможно поместить индекс в IsDeleted , если вычисление основано на текущей дате / времени , поскольку результат вычисляемого столбца является недетерминированным. Это основано на времени и потенциально может иметь разные результаты при каждом вызове. См. Эту статью MSDN для деталей:

Например, если в таблице есть целое число столбцы a и b, вычисляемый столбец a + b может быть проиндексирован, но вычислен столбец a + DATEPART (дд, GETDATE ()) не может быть проиндексирован, потому что значение может измениться в последующих вызовах.

Если сравнение дат становится слишком дорогим, вам придется планировать оператор обновления для запуска каждые 'x' раз, чтобы установить значение IsDeleted для дат 'expired':

UPDATE MyTable SET IsDeleted=1 WHERE IsDeleted=0 AND DeletedDate < getutcdate()

Редактировать : Первоначально я неправильно понял вопрос, когда вычисление NULL против ненулевого, оно будет детерминированным. С детерминированным результатом ключевое слово PERSISTED может использоваться для хранения результата проверки на нуль:

IsDeleted AS DeletedDate IS NOT NULL PERSISTED

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

Индексирование любого свойства, вероятно, не имеет особого смысла, потому что вы в основном хотите разделить 2 группы: удаленные и не удаленные.

1 голос
/ 17 декабря 2009

Размещение индекса для атрибута, значения которого ограничены очень маленьким доменом (очевидно, двухзначное является наименьшим возможным), не имеет смысла, за исключением особых крайних случаев (например, когда строки распределены на 90% -10 % между двумя значениями)

Это связано с тем, что любое использование индекса для поиска одного из значений (при условии, что строки равномерно распределены приблизительно на 50-50) вернет примерно половину всех строк в таблице. Если создаваемый вами индекс сбалансированного дерева (B-Tree) имеет глубину три или четыре уровня, это означает 3 или 4 операции ввода-вывода для каждой извлеченной строки, что будет больше, чем число строк в таблице.

0 голосов
/ 17 декабря 2009

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

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