Размер файла SQL MDF не изменяется - PullRequest
4 голосов
/ 18 сентября 2010

Изначально в моей БД у меня была одна таблица с тремя столбцами, и в то время данных не было. Размер файла MDf был 5122 КБ.

Затем я вставил 500000 записей в эту таблицу, размер файла MDF увеличился до 19456КБ

Затем я обновил свою таблицу и сделал все значения одного столбца равными Null, но размер файла остался прежним, т.е. 19456 КБ.

Затем я удалил все записи из этой таблицы, но мой размер файла MDF по-прежнему 19456 КБ.

Я хотел знать, почему размер файла не меняется?Занимает ли значение Null в столбце пробел?

Ответы [ 2 ]

7 голосов
/ 18 сентября 2010

Файл MDF не будет автоматически уменьшаться после удаления строк, если у вас не включен AUTO_SHRINK (, который не следует !)

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

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

Чтобы увидеть это:

Сценарий создания таблицы:

CREATE TABLE dbo.t
  (
     id INT IDENTITY PRIMARY KEY,
     vc VARCHAR(4000)
  )

INSERT INTO t
SELECT TOP 26 replicate(char(64 + row_number() OVER( ORDER BY (SELECT 0))), 4000) AS rn
FROM   sys.objects

Просмотр выделенных страниц:

SELECT CONVERT(CHAR(10), object_name(i.object_id)) AS table_name,
       CONVERT(CHAR(16), i.name)                   AS index_name,
       i.index_id,
       CONVERT(CHAR(10), i.type_desc)              AS index_type,
       partition_number                            AS pnum,
       rows,
       CONVERT(CHAR(12), a.type_desc)              AS page_type_desc,
       total_pages                                 AS pages
FROM   sys.indexes i
       JOIN sys.partitions p
         ON i.object_id = p.object_id
            AND i.index_id = p.index_id
       JOIN sys.allocation_units a
         ON p.partition_id = a.container_id
WHERE  i.object_id = object_id('dbo.t'); 

Возвращает:

table_name index_name       index_id    index_type pnum        rows                 page_type_desc pages
---------- ---------------- ----------- ---------- ----------- -------------------- -------------- --------------------
t          PK__t__7C8480AE  1           CLUSTERED  1           26                   IN_ROW_DATA    17

Просмотр первой страницы данных в Средство просмотра внутренних данных SQL

enter image description here

Установить для столбца значение Null

UPDATE t SET vc=NULL

Предыдущий запрос показывает, что 17 страниц по-прежнему выделены

Повторный просмотр первой страницы данных в средстве просмотра SQL Internals

enter image description here

Видно, что исходные данные все еще там и их не былоавтоматическая перестановка рядов для восстановления пространства.

5 голосов
/ 18 сентября 2010

Чтобы освободить место, вам необходимо сжать базу данных, поскольку это не делается автоматически по соображениям производительности.

Дополнительная информация:

Имеет ли значение NULLв столбце занимает место?

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