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

26

Я плохо разбираюсь в SQL, но у меня есть база данных для обслуживания.

Для этого почти не осталось места, поэтому я решил удалить все данные, скажем, за 2008 год. После выполнения запроса на удаление (было очищено около 10 000 000 строк) и очистки журнала транзакций я обнаружил, что мой действия не влияли на размер базы данных. Есть ли что-то еще, что я должен сделать?

Марат
источник

Ответы:

16

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

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

Я написал в блоге об этом, где я увещевал людей: « Не прикасайтесь к этой термоусадочной кнопке! », Но иногда ... Иногда вам нужно. Если у вас есть большая база данных, вы только что освободили значительное пространство и не рассчитываете на ее дальнейшее увеличение - хорошо, тогда можно считать сжатие однократной операцией, если впоследствии вы сможете позаботиться о фрагментации индекса с помощью перестройки их. Операция сжатия может занимать много времени, поэтому вам нужно запланировать ее на время, когда вы можете заплатить эту цену за работу сокращения. Подход к созданию пустой БД и копированию в нее данных работает, но это может стать очень трудным с большими базами данных и большим количеством данных.

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

Также Вы сказали, что «очистили» свой журнал транзакций. Мне было бы любопытно узнать, как вы это сделали, но, прочитав пост, которым я поделился, и другие статьи этой серии, вы увидите несколько советов по управлению журналом транзакций. Но вкратце - если вы находитесь в режиме полного восстановления, вы должны регулярно делать резервные копии журналов, чтобы журнал сам себя использовал повторно. В противном случае - без резервного копирования журнала в полноэкранном режиме - файл журнала продолжает расти, расти и расти и всегда сохраняет то, что вы сделали, потому что вы сказали SQL, что вы не просто хотите поддерживать этот журнал для восстановления после сбоя, но хотите сохранить его ручное резервное копирование для воспроизведения транзакций / отмены транзакций для восстановления к определенному моменту времени для целей восстановления ... Если у вас все просто и вы видите, что журнал чрезмерно растет,BEGIN TRAN ... do work.... COMMIT TRANили вы просто сделали одно большое DELETEзаявление и удалили целый беспорядок данных в одной неявной транзакции.)

Я также предполагаю, что вы ищете это свободное место в вашей файловой системе. Если вы ищете его в SQL и в том большом файле, который у вас есть - возможно, вы ожидаете завершения очистки ghost, если ищете сразу после своей операции. Пол Рэндал пишет о Ghost Cleanup .

Майк Уолш
источник
9

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

Вам нужно сжать базу данных после удаления строки.

SQL Server 2005 DBCC SHRINKDATABASE (Transact-SQL)

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

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

Джон Сиу
источник
4

НЕ СУШИТЕ СВОЮ БАЗУ ДАННЫХ!

«Почему это происходит? Операция сжатия файла данных работает с одним файлом за раз и использует растровые изображения GAM (см. Внутри механизма хранения: GAM, SGAM, PFS и другие карты размещения), чтобы найти самую высокую страницу, выделенную в файл. Затем он перемещает его как можно дальше к началу файла и т. д. и т. д. В приведенном выше случае он полностью изменил порядок кластеризованного индекса, превратив его из идеально дефрагментированного в идеально фрагментированный. "

http://www.sqlskills.com/BLOGS/PAUL/post/Why-you-should-not-shrink-your-data-files.aspx

«Посмотрите на иронию Сжатия базы данных. Один человек сжимает базу данных, чтобы получить пространство (думая, что это поможет производительности), что приводит к увеличению фрагментации (снижению производительности). Чтобы уменьшить фрагментацию, один перестраивает индекс, что приводит к размеру базы данных, чтобы увеличить намного больше, чем первоначальный размер базы данных (до сжатия). Ну, сжимая, не получалось то, что он искал обычно ".

http://blog.sqlauthority.com/2011/01/19/sql-server-shrinking-database-is-bad-increases-fragmentation-reduces-performance/

Джимбо
источник
1
Вы должны переместить данные в новую файловую группу, а затем удалить старую файловую группу. Таким образом, вы не получаете фрагментации и можете уменьшить свою базу данных.
Али Разеги
2

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

Амриндер Сингх
источник
1

Я нашел это, потому что я просто удалил кучу таблиц резервных копий, потому что моя база данных "исчерпана". Я продолжал смотреть на свойство "Размер", думая, почему это не становится меньше? , Прочитав это, нет, я не хочу сокращать базу данных. То, что я хочу сделать, это "освободить" место для мусора, который я только что удалил. То, на что я должен был смотреть, было "Доступное место". Я думаю, может быть, это то, что кому-то еще может понадобиться посмотреть на это тоже .?*

Хосетта Каудилл
источник
0

Стоит также отметить, что если таблица имеет индексы, фрагментация может существовать после удаления больших массивов данных. У меня сегодня была таблица с ~ 70M записями, занимающая около 13 ГБ. Я очистил его до 1639 записей (остальные были сгенерированы одной ошибкой), но таблица все еще занимала около 4,5 ГБ. После того, как я перестроил все индексы в таблице, он занял всего 85 страниц (680 КБ). После этого я использовал инкрементальный shrinkfile, чтобы освободить место (и исправил ошибку в системе, чтобы предотвратить повторение).

Г.Смит
источник