есть ли преимущество у varchar (500) над varchar(8000)?
Я читал об этом на форумах MSDN, и здесь, и я все еще не ясно. Я думаю, что это правильно: Varchar (max) будет храниться как текстовый тип данных, так что имеет недостатки. Итак, допустим, ваше поле будет надежно под 8000 символов. Как поле BusinessName в моей таблице базы данных. На самом деле, название компании, вероятно, всегда будет под (вытаскивая номер из моей шляпы) 500 символов. Похоже, что множество полей varchar, с которыми я сталкиваюсь, хорошо подпадают под количество символов 8k.
Так я должен сделать это поле varchar (500) вместо varchar(8000)? Насколько я понимаю, в SQL нет никакой разницы между этими двумя. Итак, чтобы облегчить жизнь, я бы хотел определить все мои поля varchar как varchar(8000). Есть ли у этого какие-то недостатки?
по теме: размер столбцов varchar (Я не чувствовал, что этот ответил на мой вопрос).
5 ответов:
с точки зрения обработки, это не будет иметь значения, чтобы использовать varchar(8000) против varchar(500). Это скорее "хорошая практика", чтобы определить максимальную длину, которую должно содержать поле, и сделать ваш varchar такой длиной. Это то, что может быть использовано для проверки данных. Например, аббревиатура штата должна состоять из 2 символов, а почтовый индекс-из 5 или 9 символов. Раньше это было более важным различием, когда ваши данные взаимодействовали с другими системы или пользовательские интерфейсы, где длина поля была критической (например, набор данных плоского файла мэйнфрейма), но в настоящее время я думаю, что это больше привычка, чем что-либо еще.
одним из примеров, где это может иметь значение, является то, что он может предотвратить оптимизацию производительности, которая позволяет избежать добавления информации о версии строк в таблицы с триггерами after.
это покрывается SQL киви здесь
фактический размер хранящихся данных не имеет значения-это потенциал размер имеет значение.
аналогично при использовании оптимизированных таблиц памяти с 2016 года можно было использовать LOB столбцы или комбинации ширины столбцов, которые потенциально могут превышать ограничение inrow, но со штрафом.
(Max) столбцы всегда хранятся вне строки. Для других столбцов, если размер строки данных в определении таблицы может превышать 8 060 байт, SQL Server выталкивает самые большие столбцы переменной длины вне строки. Опять же, это не зависит от количества данных, которые вы храните там.
это может иметь большой отрицательный эффект на потребление памяти и производительность
еще один случай, когда над объявлением ширины столбцов может иметь большое значение, если таблица будет когда-либо обрабатываться с помощью SSIS. Память, выделенная для столбцов переменной длины (не BLOB), фиксируется для каждой строки в дереве выполнения и соответствует объявленной максимальной длине столбцов, что может привести к неэффективному использованию буферов памяти (пример). Хотя разработчик пакета служб SSIS может объявить меньший размер столбца, чем исходный этот анализ лучше всего сделать это заранее и принудительно там.
назад в самом SQL Server engine аналогичный случай заключается в том, что при вычислении гранта памяти для выделения
SORT
операции SQL Server предполагает, чтоvarchar(x)
столбцы будут в среднем потреблятьx/2
байт.если большая часть вашего
varchar
столбцы полнее, чем это может привести кsort
операции разлива доtempdb
.в вашем случае, если ваш
varchar
столбцы объявлены как8000
байт но на самом деле имеют содержание гораздо меньше, чем то, что ваш запрос будет выделена память, что он не требует, что явно неэффективно и может привести к ожиданиям грантов памяти.это описано в части 2 веб-трансляции семинаров SQL 1 скачать здесь или см. ниже.
use tempdb; CREATE TABLE T( id INT IDENTITY(1,1) PRIMARY KEY, number int, name8000 VARCHAR(8000), name500 VARCHAR(500)) INSERT INTO T (number,name8000,name500) SELECT number, name, name /*<--Same contents in both cols*/ FROM master..spt_values SELECT id,name500 FROM T ORDER BY number
SELECT id,name8000 FROM T ORDER BY number
помимо лучших практик (ответ BBlake)
- вы получаете предупреждения о максимальном размере строки (8060) байт и ширину индекса (900 байт) с DDL
- DML умрет, если вы превысите эти пределы
- заполнение ANSI по умолчанию, так что вы можете в конечном итоге хранить всю нагрузку пробелов
есть некоторые недостатки для больших столбцов, которые немного менее очевидны и могут поймать вас немного позже:
- все столбцы, которые вы используете в индекс - не должно превышать 900 байт
- все столбцы в элементе ПРИКАЗОМ пункте, не может превышать 8060 байт. Это немного трудно понять, так как это относится только к некоторым столбцам. Смотрите превышен предел размера строки SQL 2008 R2 дополнительные сведения)
- Если строку "итого" размер превышает 8060 байт, вы получаете "разлива страницы" для этой строки. Это может повлиять на производительность (страница является единицей распределения в SQLServer и фиксируется на 8000 байт+некоторые накладные расходы. Превышение этого не будет серьезным, но это заметно, и вы должны стараться избегать его, если вы легко можете)
- многие другие внутренние структуры данных, буферы и не в последнюю очередь ваши собственные переменные и табличные переменные должны отражать эти размеры. С чрезмерными размерами, чрезмерно память распределение может повлиять на производительность
Как правило, старайтесь быть консервативным с шириной столбца. Если это становится проблемой, вы можете легко расширить его в соответствии с потребностями. Если вы заметите проблемы с памятью позже, сокращение широкого столбца позже может стать невозможным без потери данных, и вы не будете знать, с чего начать.
в вашем примере названия компаний, подумайте о том, где вы получите, чтобы отобразить их. Есть ли действительно место для 500 символов?? Если нет, то есть мало смысла хранить их как таковые. http://en.wikipedia.org/wiki/List_of_companies_of_the_United_States перечисляет некоторые названия компаний, и Макс составляет около 50 символов. Поэтому я бы использовал 100 для столбца макс. Может быть, больше 80.
В идеале вы хотели бы пойти меньше, чем это, вплоть до разумного размера длины (500 не является разумным размером) и убедитесь, что проверка клиента ловит, когда данные будут слишком большими и отправить полезную ошибку.
хотя varchar на самом деле не собирается резервировать пространство в базе данных для неиспользуемого пространства, я вспоминаю версии SQL Server, имеющие snit о том, что строки базы данных шире, чем некоторое количество байтов (не помню точного количества) и фактически выбрасывают какие бы данные не подходили. Определенное количество этих байтов было зарезервировано для внутренних объектов SQL Server.