Влияет ли varchar на производительность, вызванную фрагментацией данных?

Как столбцы varchar обрабатываются внутренне с помощью механизма базы данных? Для столбца, определенного как char (100), СУБД выделяет 100 смежных байтов на диске. Однако для столбца, определенного как varchar (100), это, по-видимому, не так, поскольку вся точка varchar не должна выделять больше места, чем требуется для хранения фактического значения данных, хранящегося в столбце. Итак, когда пользователь обновляет строку базы данных, содержащую пустой столбец varchar (100), до значения, состоящего, например, из 80 символов, где выделяется пространство для этих 80 символов? Похоже, что столбцы varchar должны приводить к достаточной фрагментации фактических строк базы данных, по крайней мере, в сценариях, где значения столбца первоначально вставляются как пустые или NULL, а затем обновляются позже с фактическими значениями. Оказывает ли эта фрагментация ухудшение производительности в запросах базы данных, в отличие от использования значений типа char, где пространство для столбцов, хранящихся в строках, распределено смежно? Очевидно, что использование varchar приводит к меньшему объему дискового пространства, чем при использовании char, но есть ли производительность при оптимизации производительности запросов, особенно для столбцов, значения которых часто обновляются после начальной вставки?

Ответ 1

Структуры данных, используемые внутри механизма базы данных, намного сложнее, чем вы даете ему кредит! Да, есть проблемы фрагментации и проблемы, при которых обновление varchar с большим значением может привести к поражению производительности, однако его трудно объяснить/понять, что последствия этих проблем не имеют более полного понимания связанных с ними структур данных.

Для сервера MS Sql вы можете начать с понимания страниц - фундаментальной единицы хранения (см. http://msdn.microsoft.com/en-us/library/ms190969.aspx)

С точки зрения влияния производительности на версии с фиксированными значениями vs для переменных производительности есть несколько моментов:

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

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

На этом этапе я также порекомендую отличную книгу "Microsoft Sql Server 2008 Internals" для более глубокого понимания того, насколько сложны такие вещи, как это действительно!

Ответ 2

Вы делаете много предположений в своем вопросе, которые не обязательно верны.

Тип столбца в любой СУБД вообще ничего не говорит о характере хранения этих данных, если в документации явно не указано, как хранятся данные. ЕСЛИ это не указано, вы не знаете, как оно хранится, и СУБД может свободно менять механизм хранения с момента выпуска до выпуска.

Фактически некоторые базы данных хранят поля CHAR внутри себя как VARCHAR, в то время как другие принимают решение о том, как хранить столбец на основе объявленного размера столбца. Некоторые хранилища данных VARCHAR с другими столбцами, некоторые с данными BLOB, а некоторые реализуют другое хранилище. Некоторые базы данных всегда переписывают всю строку при обновлении столбца, другие - нет. Некоторые пэды VARCHAR, чтобы обеспечить ограниченное будущее обновление без перемещения хранилища.

СУБД несет ответственность за выяснение того, как хранить данные и возвращать их вам скорейшим и последовательным образом. Меня всегда поражает, сколько людей пытается опробовать базу данных, как правило, перед обнаружением любой проблемы с производительностью.

Ответ 3

Ответ будет зависеть от конкретной СУБД. Для Oracle, безусловно, возможно в конечном итоге фрагментация в виде "цепочек строк", и это приводит к штрафу за производительность. Тем не менее, вы можете смягчить это, предварительно выделив некоторое пустое пространство в табличных блоках, чтобы разрешить некоторое расширение из-за обновлений. Однако столбцы CHAR, как правило, делают таблицу намного больше, что влияет на производительность. CHAR также имеет другие проблемы, такие как пустые сравнения, которые означают, что в Oracle использование типа CHAR почти никогда - хорошая идея.

Ответ 4

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

Как вы предположили, было бы интересно посмотреть, что произойдет, если вы напишете вставить все записи с пустой строкой (""), а затем обновите их, чтобы иметь 100 символов, которые являются достаточно случайными, а не только 100 Xs.

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

Ответ 5

Это будет полностью конкретная база данных.

Я знаю, что в Oracle база данных будет резервировать определенный процент каждого блока для будущих обновлений (параметр PCTFREE). Например, если для PCTFREE установлено значение 25%, тогда блок будет использоваться только для новых данных, пока он не будет заполнен на 75%. Делая это, комната остается для роста строк. Если строка растет настолько, что зарезервированное пространство на 25% полностью израсходовано, тогда вы получите цепочку строк и штраф за производительность. Если вы обнаружите, что таблица имеет большое количество цепочечных строк, вы можете настроить PCTFREE для этой таблицы. Если у вас есть таблица, в которой никогда не будет никаких обновлений, PCTFREE нуля будет иметь смысл

Ответ 6

В SQL Server varchar (кроме varchar (MAX)) обычно сохраняется вместе с остальными данными строки (на той же странице, если данные строки составляют < 8KB и в той же степени, если она равна < 64 КБ. Только большие типы данных, такие как TEXT, NTEXT, IMAGE, VARHCAR (MAX), NVARHCAR (MAX), XML и VARBINARY (MAX) хранятся отдельно.