Наш проект работает с очень большой, очень сложной базой данных. Примерно месяц назад мы заметили, что пространство, используемое индексированными столбцами, содержащими нулевые значения, становится слишком большим. В ответ на это я написал в виде сценария, который будет динамически выполнять поиск по всем одноколоночным индексам, содержащим более 1% нулевых значений, а затем отбрасывать и воссоздавать эти индексы как отфильтрованные индексы при условии, что значение равно NOT NULL. Это приведет к удалению и воссозданию сотен индексов по всей базе данных и, как правило, освобождает почти 15% пространства, используемого всей БД.
Теперь у меня есть два вопроса по этому поводу:
А) Каковы недостатки использования фильтрованных индексов таким способом? Я бы предположил, что это только улучшит производительность, но есть ли какие-либо риски производительности?
B) Мы получили ошибки ( «не могу удалить индекс XYZ, потому что он не существует или у вас нет разрешения» ) при удалении и повторном создании индексов, хотя при последующей проверке все прошло точно так, как ожидалось. Как это может случиться?
Спасибо за любую помощь!
Изменить: в ответ на @ Томас Кейсер
Привет и спасибо, но оказалось, что это была катастрофа. В то время мы не понимали несколько вещей, таких как:
- Во время запроса SQLOS создает планы индекса, прежде чем определить, что он не может использовать значения NULL для объединения столбцов таблицы. IE, вам действительно нужно иметь фильтр предложения WHERE, соответствующий индексу для каждого отфильтрованного индекса, используемого в запросе, иначе индекс не будет использоваться вообще.
- Удаление и создание индексов и избыточное обновление их статистики еще раз после этого может оказаться недостаточным для создания обновленных планов, как мы и предполагали. В некоторых случаях оказывается, что только достаточно высокая рабочая нагрузка заставит SQL Server пересмотреть планы.
- Есть некоторые экзотические черты в функциональности планировщика выполнения, которые трудно определить только с помощью здравого смысла и логики. Благодаря тысячам сгенерированных с помощью кода вариаций различных запросов даже, казалось бы, бесполезные индексы могут помочь в некоторых статистических данных и планах запросов, которые в конечном итоге используются в критических запросах.
В итоге эти изменения были отменены. Таким образом, отфильтрованные индексы являются мощным инструментом, но вы должны точно понимать, какие данные выбираются из этих столбцов. Там, где обычные индексы помимо проблем с пространством довольно просты в применении, отфильтрованные индексы представляют собой очень индивидуальные решения. Они, конечно, не являются заменой для обычного индекса, а скорее являются дополнением к ним в тех особых обстоятельствах, которые им необходимы.
Ответы:
Очень интересный подход. Мой голос за творчество.
Поскольку вы освободили место, я предполагаю, что исходные индексы больше не на месте? Недостатками отфильтрованных индексов являются:
С практической точки зрения это означает, что вы должны быть чрезвычайно осторожны с отфильтрованными индексами, поскольку они часто приводят к ужасным планам запросов. Я бы не стал называть их бесполезными, но я рассматриваю их как дополнение к традиционным индексам, а не как замену (как вы пытаетесь это сделать).
источник
Томас Кейсер ответит на эту тему намного выше.
Я просто думал о добавлении 2 центов.
Я видел, что некоторые отфильтрованные индексы использовались (показанные в плане выполнения) только тогда, когда вы точно совпадали с предложением where в вашем запросе и где в фильтрованном индексе.
Вы пытались использовать индексированные представления ? редкие столбцы ?
Я считаю, что, поскольку у вас есть только внутренние соединения, вы можете создать индексированное представление, содержащее предложения where ваших отфильтрованных индексов, а затем вы можете использовать представление вместо этого.
Там может быть более одного взгляда. Но так же, как с некластеризованными индексами, слишком много замедлит вашу запись.
По моему опыту, у вас были бы хорошие результаты при чтении, но вам пришлось бы отслеживать записи (вставки и обновления), особенно если таблицы участвуют в репликации.
Тем не менее, насколько я понимаю, ваша главная проблема
the null values
заключается в том, что я бы предложил вам колонки SPARSE в ваших индексах .Разреженные столбцы особенно подходят для отфильтрованных индексов
Поскольку я рекламировал разреженные столбцы, я бы не чувствовал себя хорошо, если бы я не рассказал вам и о его ограничениях:
Как результат этого
Рассмотрим> пример таблицы с 600 разреженными столбцами типа bigint.
подробнее по ссылке выше, однако я предпочитаю размещать здесь и это предупреждение:
Модуль базы данных SQL Server использует следующую процедуру для выполнения этого изменения:
1 - добавляет новый столбец в таблицу в новом размере и формате хранилища.
2 - Для каждой строки в таблице обновляет и копирует значение, сохраненное в старом столбце, в новый столбец.
3 - Удаляет старый столбец из схемы таблицы.
4 - Перестраивает таблицу (если нет кластеризованного индекса) или перестраивает кластеризованный индекс, чтобы освободить пространство, используемое старым столбцом.
источник