Пустые столбцы занимают место в таблице?

20

У меня есть таблица, которая содержит очень основную информацию. Просто заголовок и несколько полей даты. Есть одно поле с именем comments, которое называется varchar (4000). В большинстве случаев мы оставляем это поле пустым, но иногда здесь вводится большое количество данных. Это действительно плохой дизайн? Или это просто немного неэффективно?

Я бы предположил, что создание отдельной таблицы для этого столбца будет лучше.

примечание: это SQL Server 2008

введите описание изображения здесь

Арон
источник
Спасибо всем за отзывы! Я решил сделать это простым и оставить столбец в таблице, а не поместить его в другую таблицу. Однако в SQL 2008 я использовал функцию SPARSE, поэтому в поле не используется пробел.
2
Просто любопытно, что такое "большую часть времени"? Сколько всего строк и какой процент имеет значение здесь? Просто интересно, планируете ли вы проводить какие-либо сравнения пространства / производительности, используя SPARSEи не используя SPARSE...
Аарон Бертран

Ответы:

9

Для более предсказуемой производительности (и во избежание большого разброса строк на странице) я бы предпочел хранить эти данные в связанной таблице, особенно если они заполнены небольшим процентом времени, особенно если они извлекаются только в некоторые из запросов. Строки, в которых это значение NULL, вносят вклад в пространство, но это минимально. Более важным будет то, как одна страница может уместиться только в две строки, а следующая страница может уместиться в 500 строк - это действительно может повлиять на статистику, и вам лучше разбить ее на части, чтобы она сохранялась отдельно и не влияла на все ваши операции на основной стол.

Аарон Бертран
источник
12

Занимает минимум места, когда не используется

  • один бит в битовой карте NULL
  • два байта для длины (которая будет нулевой, когда NULL)

Затраты минимальны, и оптимизация будет преждевременной.

Пока вы не знаете, что у вас есть проблема, просто держите ее в одном столе. Вы нарушаете KISS, вводя внешние объединения и добавляя накладные расходы при запросе данных.

См. Https://stackoverflow.com/questions/3793022/how-to-come-to-limits-of-8060-bytes-per-row-and-8000-per-varchar-nvarchar-valu/3793265#3793265 для получения дополнительной информации.

ГБН
источник
10

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

  • Страница данных хранится вокруг 8000 байт
  • У вас есть несколько строк, скажем, 100 байтов, а некоторые строки с более чем 4000 байтов
  • Эти длинные строки будут на странице сами по себе, а остальная часть страницы будет «потрачена впустую» пространство, которое занимает ваша БД, но, вероятно, никогда не будет содержать данные
  • Если вы добавите данные в это длинное поле для записи на почти полной странице, это, вероятно, приведет к переполнению страницы и приведет к указателю на страницу с остальной частью записи.

Все эти пустые страницы и указатели ведут к снижению производительности. Нормализуйте это поле, если можете.

JNK
источник
4

Этот вопрос выглядит очень похоже: действительно ли лишние пустые столбцы влияют на размер таблицы SQL?

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

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

Сообщество
источник
2
Чтобы быть явным, алгоритм сжатия применяется только к тем столбцам, которые явно определены как SPARSE, а не только к «столбцам с большим количеством нулевых значений».
Аарон Бертран
2

Вы будете в порядке - это уже столбец varchar, поэтому он использует пространство только тогда, когда он содержит данные. Если у вас есть много столбцов фиксированного размера, например int, которые могут содержать значения NULL, у вас могут возникнуть проблемы с использованием пространства.

Что касается помещения в другой стол, я бы не стал беспокоиться. Вы также можете посмотреть на использование параметров varchar (max) и in / out of row. Опять наверное преждевременно.

Кейд Ру
источник
1
Преждевременная оптимизация часто может быть реальной проблемой, но это зависит от стоимости рефакторинга позже. Если сегодня вы знаете, что только в 1% ваших строк будут данные в этом столбце, и вы ожидаете, что таблица со временем станет большой, какова ценность сохранения этих данных в текущей таблице, которые будут иметь последствия только при масштабировании? Я за то, чтобы избежать преждевременной оптимизации, но есть момент, когда я оцениваю долгосрочный эффект от этого.
Аарон Бертран
@ Аарон Бертран Согласен. Люди задают вопросы о производительности здесь, и легко предположить, что у них может быть приложение, которое состоит из миллионов строк, и им нужно использовать каждое оружие в наборе инструментов и помнить все это. С другой стороны, иногда кажется, что пользователь находится в начале кривой обучения, и трудно попросить его посвятить время чему-то, что, вероятно, должно быть ниже их приоритетов. Кроме того, с помощью varchar (max) вы можете нажать переключатель, чтобы начать хранение вне строки. Я думаю, что реальный ответ здесь - «Вы действительно не дали нам достаточно информации, чтобы дать окончательный ответ».
Кейд Ру