2010-09-18 3 views
4

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

Тогда я вставил 500000 записей в этой таблице, MDF размера файла увеличены до 19456 KB

Тогда я обновил свой стол и сделали все значения одного столбца, как Null, но размер файла еще же есть 19456 KB.

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

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

ответ

5

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

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

Нулевое значение в столбце имеет ли место?

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

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

Что касается того, занимают место это зависит от типа данных значения 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 Internals Viewer

enter image description here

Установите колонку обнулить

UPDATE t SET vc=NULL 

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

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

enter image description here

Можно видеть, что исходные данные по-прежнему там, и там не было никакой автоматической перестановки строк, чтобы вернуть пространство.

+0

+1 Действительно хороший ответ и научил меня новому инструменту. –

Смежные вопросы