Должен ли я использовать varchar(255)
или varchar(256)
при разработке таблиц? Я слышал, один байт используется для длины столбца или для хранения метаданных.
Имеет ли это значение в данный момент?
Я видел некоторые посты в интернете, однако они относятся к Oracle и MySQL.
У нас есть Microsoft SQL Server 2016 Enterprise Edition, как это применимо к этой среде?
Скажем, например, что если я скажу своим клиентам, например, оставить текстовое описание 255 символов вместо 256, есть ли разница? Что я прочитал: «При максимальной длине в 255 символов СУБД может выбрать использование одного байта для указания длины данных в поле. Если бы ограничение было 256 или больше, потребовалось бы два байта». Это правда?
Ответы:
Размер каждого столбца соответственно. НЕ используйте «стандартный» размер для каждого столбца. Если вам нужно только 30 символов, зачем создавать столбец, который может обрабатывать 255? Я так рад, что вы не пропагандируете использование
varchar(max)
для своих строковых столбцов.Это особенно разумный совет, если вам когда-либо нужно проиндексировать столбец, или если вы используете столбец в качестве первичного ключа, и у него есть ссылки на внешние ключи. SQL Server использует размер каждого столбца в оптимизаторе запросов, чтобы понять предполагаемые требования к памяти для обработки запросов. Наличие негабаритных столбцов может отрицательно сказаться на производительности.
Индексы столбцов, размер которых превышает допустимый, могут привести к возникновению ошибок:
Попытка создать индекс выше приводит к этому предупреждению:
900 байтов - это максимальный размер ключа для кластеризованных индексов (и некластеризованных индексов в SQL Server 2012 и более ранних версиях). 1700 байт - это максимальный размер ключа для некластеризованных индексов в новых версиях SQL Server. Если вы проектируете столбцы с общей шириной, такой как (255), вы можете столкнуться с этим предупреждением гораздо чаще, чем ожидалось.
Если вас интересуют внутренние устройства хранения, вы можете использовать следующий небольшой тест, чтобы лучше понять, как SQL Server хранит несжатые данные хранилища строк.
Сначала мы создадим таблицу, в которой мы можем хранить столбцы разных размеров:
Теперь мы вставим одну строку:
Этот запрос использует недокументированные и неподдерживаемые функции
sys.fn_RowDumpCracker
иsys.fn_PhyslocCracker
показывает некоторые интересные детали о таблице:Вывод будет выглядеть примерно так:
Как видите,
InRowLength
для каждого значения отображается вместе с физическим местом хранения каждой строки - «file_id», «page_id» и «slot_id».Если взять
file_id
иpage_id
значение из результатов запроса выше и работатьDBCC PAGE
с ними, мы можем видеть фактическое содержание физических страниц:Результаты от моей машины:
источник
Другие уже указывали, что число байтов, необходимое для хранения длины, является фиксированным. Я хотел бы сосредоточиться на этой части в вашем вопросе:
Ваш вопрос помечен корпоративной версией, что обычно означает, что у вас будет достаточно данных. Часто различия одного байта в строке на практике не имеют большого значения. Например, следующая таблица с полностью заполненным
VARCHAR(255)
столбцом занимает 143176 КБ места на диске:Результаты:
Давайте создадим вторую таблицу с полностью заполненным
VARCHAR(256)
столбцом. Это займет как минимум еще один байт на строку, верно?Результаты:
Так получилось, что обе таблицы занимают одинаковое количество места. Одинаковое количество строк умещается на каждой странице 8 КБ. Это здорово, что вы хотите потратить время на оптимизацию своего приложения, но я подозреваю, что вам лучше сосредоточиться на разных областях.
источник
Заявленный размер varchar не влияет на производительность. Данные могут фактически храниться как хранилище строк со сжатием страниц или сжатием строк. В качестве кластерного хранилища столбцов или таблицы, оптимизированной для памяти. Каждый из них будет иметь различные компромиссы в производительности, но не имеет значения, объявляете ли вы varchar (255) или varchar (256).
источник