Уменьшить фрагментацию таблицы SQL Server без добавления/удаления кластеризованного индекса?

У меня есть большая база данных (данные 90GB, индексы 70GB), которая медленно росла в течение прошлого года, и рост/изменения вызвали большое количество внутренней фрагментации не только индексов, но и самих таблиц.

легко решить (большое количество) очень фрагментированных индексов-реорганизация или перестройка позаботится об этом, в зависимости от того, насколько они фрагментированы, но единственный совет, который я могу найти по очистке фактической фрагментации таблицы, - это добавить кластеризованный индекс к таблице. Я бы сразу же отбросил его после этого, так как я не хочу, чтобы кластеризованный индекс на таблице шел вперед, но есть ли другой способ сделать это без кластеризованного индекса? Команда" DBCC", которая сделает это?

Спасибо за помощь.

5 ответов


давайте проясним, потому что это общая проблема, серьезная проблема для каждой компании, использующей SQL Server.

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

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

суть в том, что вы имеют существенную фрагментацию на кучу. Вы продолжаете называть его "таблицей", но на уровне физического хранения данных или структуры данных такого нет. Таблица-это логическое понятие, а не физическое. Это коллекция физических структур данных. Коллекция является одной из двух возможностей:

  • кучу
    плюс все некластеризованные индексы
    плюс текстовые / графические цепочки

  • или a Кластерный Индекс
    (устраняет кучу и один некластерный индекс)
    плюс все некластеризованные индексы
    плюс текстовые / графические цепочки.

кучи сильно фрагментируются; чем больше перемежающихся (случайных)вставок / удалений / обновлений, тем больше фрагментации.

нет способа очистить кучу, как есть. MS не предоставляет объект (другие поставщики делать.)

решение

однако мы знаем, что Create Clustered Index полностью перезаписывает и переупорядочивает кучу. Поэтому метод (а не трюк) заключается в создании кластеризованного индекса только с целью де-фрагментации кучи, а потом бросьте его. Вам нужно свободное пространство в БД table_size x 1.25.

пока вы на нем, непременно используйте FILLFACTOR, чтобы уменьшить будущее фрагментации. Куча затем возьмите больше выделенного пространства, что позволит в будущем вставлять, удалять и расширять строки из-за обновлений.

Примечание

  1. обратите внимание, что есть три уровень фрагментации; это касается только уровня III, фрагментации в куче, которая вызвана отсутствие кластеризованного индекса

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

ответ на комментарий

SqlRyan:
Хотя это не дает мне волшебного решения моей проблемы, довольно ясно, что моя проблема является результатом ограничения SQL Server, и добавление кластеризованного индекса является единственным способом "дефрагментации" кучи.

не совсем. Я бы не назвал это "ограничение."

  1. метод, который я дал для устранения фрагментации в куче, заключается в создании кластеризованного индекса,а затем отбросьте его. Ie. временно, единственной целью которого является исправление фрагментации.

  2. реализация кластеризованного индекса в таблице (постоянно) - гораздо лучшее решение, потому что оно уменьшает в целом фрагментация (DataStructure может по-прежнему фрагментироваться, см. подробные информация в ссылках ниже), что намного меньше фрагментации, которая происходит в куче.

    • каждая таблица в реляционной базе данных (кроме таблиц "труба" или "очередь") должна иметь кластеризованный индекс, чтобы воспользоваться его различными преимуществами.

    • кластеризованный индекс должен быть на столбцах, которые распределяют данные (избегая конфликтов вставки), никогда не индексироваться на монотонно растущем столбце, таком как идентификатор записи 1, что гарантирует вставку горячей точки На последней странице.

1. Идентификаторы записей в каждом файле делают вашу "базу данных" нереляционной системой хранения записей, используя SQL просто для удобства. Такие файлы не имеют целостности, мощности или скорости реляционных баз данных.

Эндрю Хилл:
вы могли бы прокомментировать далее "обратите внимание, что есть три уровня Фрагментация; это касается только уровня III" - каковы два других уровня фрагментации?

в MS SQL и Sybase ASE есть три уровень фрагментации, и в пределах каждого уровня, несколько различных типы. Имейте в виду, что при работе с фрагментацией мы должны сосредоточиться на структурах данных, а не на таблицах (таблица-это коллекция структур данных, как описано выше). уровень являются:

  • Уровень I * Экстра-DataStructure
    Вне соответствующей структуры данных, через или внутри базы данных.

  • уровень II * DataStructure
    В соответствующей структуре данных, над страницами (по всем страницам)
    Это уровень, к которому чаще всего обращаются DBAs.

  • уровень III * страница
    В рамках соответствующей структуры данных, в рамках страницы

эти ссылки обеспечивают полную фрагментацию re. Они специфичны для Sybase ASE, однако на структурном уровне информация относится к MS SQL.

обратите внимание, что метод, который я дал, является уровнем II, он исправляет фрагментацию уровня II и III.


вы заявляете, что добавляете кластеризованный индекс, чтобы облегчить фрагментацию таблицы, а затем немедленно отбрасываете его.

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

имело бы смысл создать этот кластеризованный ключ и сохранить его, поскольку вы, очевидно, хотите/нуждаетесь в сортировке данных таким образом. Вы говорите, что данные меняются понесет штрафы за перемещение данных, которые нельзя нести; вы думали о создании индекса с более низким FILLFACTOR чем значение по умолчанию? В зависимости от шаблонов изменения данных, вы можете извлечь выгоду из чего-то низкого, как 80%. Затем у вас есть 20% "неиспользуемого" пространства на страницу, но преимущество нижней страницы разбивается при изменении значений кластеризованных ключей.

может вам помочь?


вы можете компактный куча, запустив DBCC SHRINKFILE с NOTRUNCATE.

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

чтобы представить это в перспективе, у нас есть база данных с 10 миллионами новых строк в день с кластеризованными индексами на всех таблицах. Удаленные "пробелы" будут удалены с помощью запланированного индекса ALTER (а также прямых указателей/разделений страниц).

ваш стол 12ГБ можно 2ГБ после индексирование: он просто имеет выделенный 12GB, но также массово фрагментирован.


Я понимаю вашу боль в том, чтобы быть ограниченным дизайном устаревшего дизайна.

У вас есть возможность восстановить резервную копию таблицы на другом сервере и создать кластерный индекс? Очень возможно, что кластеризованный индекс, созданный на наборе узких уникальных столбцов или столбце идентификатора, уменьшит общий размер таблицы (данных и индекса).

в одном из моих старых приложений все данные были доступны через вид. Я смог изменить схему базовая таблица добавление столбца идентификаторов и кластеризованного индекса без применения приложения.

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

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

эта статья от Microsoft


проблема, о которой никто не говорит, - это фрагментация файлов данных или журналов устройств на самом жестком диске(дисках)!! Все говорят о фрагментации индексов и о том, как избежать/ограничить эту фрагментацию.

FYI :при создании базы данных вы указываете начальный размер.МДФ вместе с тем, насколько он будет расти, когда ему нужно расти. Вы делаете то же самое с .файл LDF. НЕТ НИКАКОЙ ГАРАНТИИ, ЧТО КОГДА ЭТИ ДВА ФАЙЛА РАСТУТ, ЧТО ДИСКОВОЕ ПРОСТРАНСТВО, ВЫДЕЛЕННОЕ ДЛЯ НЕОБХОДИМОЕ ДОПОЛНИТЕЛЬНОЕ ДИСКОВОЕ ПРОСТРАНСТВО БУДЕТ ФИЗИЧЕСКИ СМЕЖНЫМ С СУЩЕСТВУЮЩИМ ДИСКОВЫМ ПРОСТРАНСТВОМ!!

каждый раз, когда один из этих двух файлов устройств должен расширяться, есть возможность фрагментации жесткого диска дискового пространства. Это означает, что руководители на жестком диске должны работать усерднее (и занять больше времени), чтобы перейти от одной секции жесткого диска к другой секции для доступа к необходимым данным в базе данных. Это аналогично покупке небольшого участка земли и строительству дом, который как раз подходит для этой земли. Когда вам нужно расширить дом, у вас больше нет земли, если вы не купите пустырь по соседству - за исключением - что, если кто-то другой, тем временем, уже купил эту землю и построил на ней дом? Тогда вы не сможете расширить свой дом. Единственная возможность купить еще один участок земли в "микрорайоне" и построить еще один дом на нем. Проблема в том , что вы и двое ваших детей будете жить в доме а, а ваша жена и третий ребенок-в доме а. жить в доме Б. Это было бы больно (до тех пор, пока вы все еще были женаты).

решение для исправления этой ситуации заключается в том, чтобы"купить гораздо больший участок земли, забрать существующий дом (т. е. базу данных), переместить его на больший участок земли, а затем расширить дом там". А как это сделать с базой данных? Сделайте полную резервную копию, удалите базу данных (если у вас нет свободного места на диске, чтобы сохранить как старую фрагментированную базу данных-на всякий случай - так и новую базу данных), создайте совершенно новую базу данных с большим количеством выделенного начального дискового пространства (нет гарантии, что операционная система обеспечит непрерывность запрашиваемого пространства), а затем восстановите базу данных в новом только что созданном пространстве базы данных. Да-это боль, но я не знаю ни одного программного обеспечения" автоматического дефрагментатора диска", которое будет работать с файлами базы данных SQL.