2009-09-09 1 views
56

После перехода к некоторым учебникам по новой функции SQL SERVER 2008 SPARSE COLUMN, я обнаружил, что это не занимает места, если значение столбца равно 0 или null, но когда есть значение, требуется 4 раз пространство, в котором выполняется регулярный (не разреженный) столбец.Почему и когда следует использовать SPARSE COLUMN? (SQL SERVER 2008)

Если мое понимание верное, то почему я пойду за это во время проектирования базы данных? И если я использую это, то в какой ситуации я буду?

Также из любопытства, как же запас никакого пространства ПОЛУЧИТЬ, когда столбец определен как разреженный колонке (я имею в виду, что внутренняя реализация для этого)

Заранее спасибо

+0

Эта ссылка из [MSDN] (https://msdn.microsoft.com/en-us/library/cc280604.aspx) содержит табличные данные, показывающие экономию пространства w.r.t. каждый тип данных. Может быть действительно хорошим указателем в этом отношении. – RBT

+0

Очень хорошо читать на разреженных колонках вообще [здесь] (https://www.simple-talk.com/sql/t-sql-programming/null-friendly-using-sparse-columns-and-column-sets- в-SQL-сервер /). – RBT

ответ

74

Разреженный колонок не используется 4x объема пространства для хранения значения, он использует (фиксированные) 4 дополнительных байты на ненулевое значение. (Как вы уже говорилось, NULL занимает 0 место.)

  • Так непустое значение, хранящееся в битном колонки будет 1 бит + 4 байта = 4,125 байт. Но если 99% из них NULL, это по-прежнему чистая экономия.

  • Не пустое значение, хранящееся в столбце GUID (UniqueIdentifier) ​​: 16 байтов + 4 байта = 20 байт. Поэтому, если только 50% из них являются NULL, это все еще чистая экономия.

Так что «ожидаемая экономия» в значительной степени зависит от того, что вид колонны мы говорим, и ваша оценка какой пропорции будет нулевым против ненулевым. Колонки переменной ширины (varchars), вероятно, немного сложнее предсказать точно.

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

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

  • A «заказа Дата возвращения» столбец в таблице заказа. Вы надеетесь, что очень небольшой процент продаж приведет к возврату продуктов.
  • A "4-й адрес" строка в адресной таблице. Большинство почтовых адресов, даже если вам нужно название отдела и «Уход», возможно, не нужны 4 отдельные строки.
  • A "Суффикс" столбец в таблице клиентов. У довольно низкого процента людей есть «младший», или «III» или «Esquire» после их имени.
+3

Было предложено изменить, что это 4 дополнительных байта за ненулевое поле *. Это неверно, я вернул это назад, чтобы сказать * row *. Чтобы пояснить пример: если у нас есть таблица из 100 строк с полем GUID, 10 строк имеют значения, 90 строк - NULL. Поле GUID обычно составляет 16 байт, поэтому обычный (не разреженный) GUID будет 16 * 100 = 1600 байт. Если бы мы сделали это разреженным полем, вместо этого использовалось бы только (16 + 4) * 10 = 200 байт, а не (16 * 10) +4 = 164 байта. 4-байтовый штраф применяется к каждой заполненной строке. – BradC

+3

Но, конечно, если в строке имеется несколько разреженных полей, то 4-байтовый штраф применяется к каждому из * полей * отдельно? В этом случае было бы более естественно говорить * за поле * (что действительно означало бы * за поле в строке *). На самом деле мне потребовалось некоторое время, чтобы понять, что ваше понимание * поля было * за поле за таблицу *. – GSerg

+0

Да, вам нужно было бы рассчитать предсказанный штраф отдельно для нескольких разреженных полей в одной таблице. Я думаю, было бы разумно оценить их вместе, если вы ожидаете, что они совпадут (например, если у вас есть 5 полей, которые заполняются только в том случае, если товар возвращается или что-то еще). – BradC

21
  • Сохранение нуля в разреженной колонке не занимает места вообще.

  • Для любого внешнего приложения столбец будет вести себя так же

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

  • Вы можете создать столбец, расположенный над разреженными столбцами, который возвращает клип xml всех ненулевых данных из столбцов, охватываемых множеством. Набор столбцов ведет себя как сам столбец. Примечание. У вас может быть только один столбец для каждой таблицы.

  • Изменение данных Захват и репликация транзакций работают, но не функция набора столбцов.

Downsides

  • Если разреженный столбец имеет данные в нем будут принимать 4 байта больше, чем в обычной колонке, например даже бит (обычно 0,125 байта) составляет 4,255 байта, а уникальный идентификатор увеличивается от 16 до 20 байт.

  • Не все типы данных могут быть разреженными: текст, ntext, изображение, метка времени, определяемый пользователем тип данных, геометрия или география или varbinray (max) с атрибутом FILESTREAM не могут быть разрежены. (Changed17/5/2009 благодарит Алекс за пятнистость опечатка)

  • вычисляемые столбцы не могут быть редкими (хотя разреженные столбцы могут принимать участие в расчете на другой вычисляемого столбца)

  • Вы не можете применить правила или имеют значения по умолчанию.

  • Редкие столбцы не могут быть частью кластерного индекса. Если вам нужно это сделать, используйте вычисленный столбец на основе разреженного столбца и создайте кластеризованный индекс на этом (какой вид поражения объекта).

  • Объединить репликацию не работает.

  • Сжатие данных не работает.

  • Доступ (чтение и запись) к разреженным столбцам дороже, но я не смог найти точных данных об этом.

Reference

+0

Спасибо .. Я уже рассмотрел этот сайт. Но даже на этом сайте не удалось ответить на вопросы, которые я задал здесь. В какой ситуации я должен идти с разреженной колонкой, когда это занимает в 4 раза больше места! –

3

Вы читаете это неправильно - он никогда не занимает 4x места.

В частности, он говорит 4 * (4 байта, см. Сноску), а не 4x (умножить на 4). Единственный случай, когда это ровно 4x, это символ char (4), который будет видеть экономию, если NULL существуют более чем в 64% случаев.

«* Длина равна среднему числу данных, содержащихся в типе, плюс 2 или 4 байта».

-2

С SQL SERVER – 2008 – Introduction to SPARSE Columns – Part 2 по Pinal Dave:

Все разреженные столбцы хранятся в виде одного столбца XML в базе данных. Дадим некоторые преимущества и недостатки столбца SPARSE.

Преимущества разреженных колонки являются:

  • INSERT, UPDATE и DELETE операторы могут ссылаться на разреженные столбцы по имени. Столбец SPARSE может работать как один столбец XML.

  • В колонке SPARSE можно использовать отфильтрованные индексы, в которых данные заполняются в строке.

  • Столбец SPARSE экономит много пространства базы данных, когда в базе данных имеются нулевые или нулевые значения.

Недостатки разреженного столбца:

  • SPARSE столбец не имеет IDENTITY или ROWGUIDCOL собственность.

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

  • Столбец SPARSE не может иметь значение по умолчанию или правило или вычисленный столбец.

  • Кластерный индекс или уникальный индекс первичного ключа нельзя применять колонку SPARSE. Столбец SPARSE не может быть частью кластерного ключа индекса.

  • Таблица, содержащая колонку SPARSE, может иметь максимальный размер 8018 байт вместо обычных 8060 байт. Операция таблицы, которая включает в себя столбец SPARSE , приводит к потере производительности по регулярному столбцу.

+4

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

+2

http://blog.sqlauthority.com/2008/07/14/sql-server-2008-introduction-to-sparse-columns-part-2/ –

+0

Я собираюсь повысить это. Объяснение всех разреженных полей, хранящихся в одном поле XML, немного облегчает мне задачу. Никто не упомянул об этом. – Brain2000

0
| datetime NULL  | datetime SPARSE NULL | datetime SPARSE NULL | 
|--------------------|----------------------|----------------------| 
| 20171213 (8 bytes) | 20171213 (12 bytes) | 20171213 (12 bytes) | 
| NULL  (8 bytes) | 20171213 (12 bytes) | 20171213 (12 bytes) | 
| 20171213 (8 bytes) | NULL  (0 bytes) | NULL  (0 bytes) | 
| NULL  (8 bytes) | NULL  (0 bytes) | NULL  (0 bytes) | 

Вы теряете 4 байта не только один раз в строке; но для каждой ячейки в строке, которая не является нулевой.