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

9

У нас есть экземпляр SQL Server, который используется для архивирования электронной почты (любезно предоставлен сторонним пакетом архивирования). Время от времени программное обеспечение переносится на новую пустую базу данных. Мы делали это ежеквартально в прошлом, но сейчас мы планируем делать это ежемесячно. Объем архивируемых данных составляет около 15–20 ГБ в месяц, а большая часть данных находится в нескольких таблицах (обычно 2–4).

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

Несколько вариантов, которые я могу придумать:

  1. REBUILD / REORGANIZE индексы, DBCC SHRINKFILE (Хорошо, это не разумный вариант, так как DBCC SHRINKFILE фрагментирует недостаток во всем, к чему он прикасается, но я включил его для полноты).
  2. Создайте новую базу данных с отключенной автоматической статистикой. Сценарий и воссоздать все таблицы из исходной базы данных. Используйте bcp для экспорта / импорта данных в новую базу данных в порядке ключей кластера. Сценарий и воссоздать все индексы. Пересчитать всю статистику с полной проверкой.
  3. Создайте новую базу данных с отключенной автоматической статистикой. Сценарий и воссоздать все таблицы из исходной базы данных. Используйте SSIS или T-SQL для передачи данных в новую базу данных. Сценарий и воссоздать все индексы. Пересчитать всю статистику с полной проверкой.

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

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

Редактировать:

Следует отметить, что около 75% данных, похоже, хранятся в столбцах изображений (LOB).

db2
источник
3
Вас (или приложение) заботит, физически ли таблицы попадают в файловую группу, кроме PRIMARY?
Джон Зигель
@JonSeigel Я полагаю, нет, и на самом деле это довольно хорошая идея, так как это избавило бы меня от необходимости создавать базу данных шаблонов и перемещать все данные.
db2
Вы рассматриваете только те решения, которые сами пишете, или вы также можете просмотреть какое-нибудь приложение, чтобы помочь вам в этом? Вы можете использовать RedGate SQL Storage Compress для сжатия данных в реальном времени. Или вы можете попробовать Виртуальное восстановление, чтобы сделать сжатые резервные копии доступными как онлайн-базы данных (фактически не имея всего необходимого места). Все они основаны на более старом драйвере файлов Hyperbac для Windows, который очень хорошо сжимает живые данные и резервные копии.
Marian
@ Мариан Звучит интересно, но я бы сейчас хотел использовать встроенные возможности SQL Server. Мне просто нужно очень эффективно дефрагментировать базы данных, не оставляя много неиспользуемого пространства в файле (ах). Если это инструмент стороннего производителя, который выполняет работу вместо сценариев вручную, это нормально.
db2
Это всего лишь мысль, но почему бы не создать новую файловую группу, добавить файл, установить разумный рост (скажем, 500 МБ), а затем перестроить ваши таблицы в эту новую файловую группу. Затем сожмите основной файл почти до нуля. Вам не придется беспокоиться о фрагментации системных таблиц.
Nic

Ответы:

1

Чтобы устранить физическую фрагментацию в файлах, вы можете переместить кластеризованный индекс с удалением в новую файловую группу. Поскольку они будут RO, сделайте их заполняющим фактором на 100%, так как для вставок не требуется места, разрывы страниц вызваны обновлениями.

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

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

Кстати, просто убедитесь, что вы используете самые последние типы данных для своих LOBS. то есть nvarchar (max) или varchar (max) вместо ntext или text, varbinary (max) вместо изображения?

Поврежденные товары
источник
К сожалению, он в основном использует текст и изображение. Это стороннее приложение, поэтому у меня нет возможности это изменить.
db2
Он действительно прозрачен для приложения, SQL-сервер хранит информацию в строке, если <8k. Если поставщик говорит, что это не поддерживается, я бы спросил их, почему они все еще используют типы данных, которые в SQL Server 2005 изначально не поддерживаются!
DamagedGoods
Я не могу быть полностью уверен, что приложение не выполняет такие специфичные для текста / изображения вещи, как WRITETEXT, которые потерпят неудачу после изменения типа данных. Но возвращаясь к основному вопросу, похоже, что воссоздание кластеризованного индекса не приведет к перемещению данных больших объектов вместе с ним.
db2
Вы можете сделать это, но вы должны войти в конструктор в графическом интерфейсе, затем развернуть свойства, затем у вас есть «обычное пространство данных», но также файловая группа TEXTIMAGE, изменив это, но будьте осторожны, это создаст таблицу заново! очевидно, вы можете
написать
Понял, что это может быть полезным способом для генерации соответствующих сценариев перестройки, по крайней мере.
db2
0

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

Лиам Конфрей
источник
Я подозреваю, что файловый поток не будет хорошо масштабироваться в этом случае. У нас более 14 миллионов строк в 17 базах данных, и мы получаем около 15 000 сообщений в день. Значительная часть тел сообщений имеет размер менее 4 КБ, поэтому отходы кластера NTFS, вероятно, будут жестокими (и это даже в том случае, если мы добавим новый том диска с размером блока меньше 64 КБ).
db2
В этом случае, можете ли вы преобразовать тип данных во что-то вроде nvarchar (max) и использовать предложение TEXTIMAGE_ON, чтобы указать другую файловую группу для этих больших объектов? Это позволит вам хранить данные вне очереди и создать собственный процесс управления архивированием.
Лиам Конфри
использование файлового потока действительно зависит от того, насколько велик каждый из больших объектов. Я думаю> 1 МБ на запись, которая будет рассмотрена. Так что я бы согласился, в этом случае это не вариант
DamagedGoods