Ищем точность о том, как происходит ROW_OVERFLOW_DATA - PullRequest
1 голос
/ 18 мая 2011

Я в настоящее время на начальных этапах планирования переписывания большого модуля в нашем приложении CRM.

Одна область, которую я сейчас изучаю, это оптимизация базы данных, я еще не принял никакого решения, но я просто хочу убедиться, что я правильно понимаю концепцию ROW_OVERFLOW_DATA - http://msdn.microsoft.com/en-us/library/ms186981.aspx

Мы используем SQL Server 2005, насколько я понимаю, ограничение размера строки составляет 8 060 байт и после этого произойдет переполнение.

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

SELECT OBJECT_NAME (sc.[id]) tablename
, COUNT (1) nr_columns
, SUM (sc.length) maxrowlength
FROM syscolumns sc
join sysobjects so
on sc.[id] = so.[id]
WHERE so.xtype = 'U'
GROUP BY OBJECT_NAME (sc.[id])
ORDER BY SUM (sc.length) desc

Это дало мне несколько таблиц с максимальной длиной, которая была чуть выше 8000, но меньше 10000. Другой запрос показывает, что средний размер строки на самом деле довольно мал, около 1000 байт.

У меня такой вопрос: основаны ли ROW_OVERFLOW_DATA на каждой строке или на столбце? После расширения предела в 8 060 байт весь столбец, вызвавший переполнение, перемещается на другую страницу или это только определенная строка?

Так, например, приведена следующая упрощенная схема:

col1 (int) | col 2 (varchar (4000)) | col 3(varchar(5000))
    1      |    4000 characters   |    5000 characters ***This row is overflowing
    2      |    4000 characters   |    100 characters
    3      |    150 characters    |    150 characters
    4      |    500 characters    |    600 characters

Будет ли каждый столбец 3 строки с 1 по 4 заменяться указателем в 24 байта или только rowID 1?

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

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

Ответы [ 2 ]

5 голосов
/ 18 мая 2011

Если у вас есть одна строка, скажем, из 100 миллионов переполнений, вы бы переместили весь столбец? Нет.

Для справки, статья от Пола Рэндала, который является богом всего этого (мой жирный)

Используемая вами функция переполнения строк отлично подходит для того, чтобы разрешить случайной строке быть длиннее 8 060 байт, но она не подходит для большинства большинства строк слишком большой размер и может привести к снижению производительности запросов, *

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

И MSDN (мой жирный)

ROW_OVERFLOW_DATA Распределительная единица

Для каждого раздела, используемого таблицей (кучей или кластеризованной таблицей), индексом или индексированным представлением, существует одна единица выделения ROW_OVERFLOW_DATA. Эта единица выделения содержит ноль (0) страниц до тех пор, пока строка данных со столбцами переменной длины (varchar, nvarchar, varbinary или sql_variant) в единице выделения IN_ROW_DATA не превысит ограничение размера строки в 8 КБ. Когда ограничение размера достигнуто, SQL Server перемещает столбец с наибольшей шириной с этой строки на страницу в единице выделения ROW_OVERFLOW_DATA. 24-байтовый указатель на эти данные вне строки сохраняется на исходной странице.

Что касается ваших пустых столбцов, это неверно. Столбцы NULLable хранятся в конце структуры диска в любом случае независимо от порядка столбцов в определении таблицы. И ссылка от Пол Рэндал: «Внутри хранилища: снова анатомия записи ». Любые некоторые предыдущие ответы от меня здесь на SO

1 голос
/ 18 мая 2011

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

Я не слышал об идее перенести NULLables в конец таблицы - мне придется проверить это!

...