Приводит ли varchar к снижению производительности из-за фрагментации данных? - PullRequest
9 голосов
/ 27 октября 2009

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

Ответы [ 6 ]

7 голосов
/ 27 октября 2009

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

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

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

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

4 голосов
/ 27 октября 2009

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

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

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

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

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

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

3 голосов
/ 27 октября 2009

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

2 голосов
/ 27 октября 2009

Это будет полностью зависит от базы данных.

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

2 голосов
/ 27 октября 2009

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

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

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

1 голос
/ 27 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...