есть ли преимущество varchar (500) перед varchar (8000)? - PullRequest
86 голосов
/ 06 января 2010

Я читал об этом на форумах MSDN и здесь, и мне до сих пор не ясно. Я думаю, что это правильно: Varchar (max) будет храниться как текстовый тип данных, поэтому у него есть недостатки. Допустим, ваше поле будет надежно содержать до 8000 символов. Как поле BusinessName в моей таблице базы данных. В действительности, название компании, вероятно, всегда будет меньше (вытаскивая число из моей шляпы) 500 символов. Кажется, что множество полей varchar, с которыми я сталкиваюсь, подпадают под число символов 8k.

Так я должен сделать это поле varchar (500) вместо varchar (8000)? Из того, что я понимаю в SQL, нет никакой разницы между этими двумя. Итак, чтобы облегчить жизнь, я бы хотел определить все мои поля varchar как varchar (8000). Есть ли у этого недостатки?

Похожие: Размер столбцов varchar (я не чувствовал, что этот ответил на мой вопрос).

Ответы [ 5 ]

119 голосов
/ 14 апреля 2011

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

Это покрыто SQL киви здесь

Фактический размер хранимых данных несущественен - ​​это потенциал размер, который имеет значение.

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

(Макс.) Столбцы всегда хранятся вне строки. Для других столбцов, если размер строки данных в определении таблицы может превышать 8 060 байт, SQL Server выталкивает самые большие столбцы переменной длины вне строки. Опять же, это не зависит от количества данных, которые вы там храните.

Это может оказать значительное негативное влияние на потребление памяти и производительность

Другой случай, когда чрезмерное объявление ширины столбцов может иметь большое значение, - это если таблица когда-нибудь будет обрабатываться с использованием служб SSIS. Память, выделенная для столбцов переменной длины (не BLOB), фиксирована для каждой строки в дереве выполнения и соответствует объявленной максимальной длине столбцов, что может привести к неэффективному использованию буферов памяти (пример) . Хотя разработчик пакета служб SSIS может объявить столбец меньшего размера, чем источник, этот анализ лучше всего выполнить заранее и применять его там.

В самом механизме SQL Server аналогичный случай заключается в том, что при расчете выделения памяти для 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

Screenshot

SELECT id,name8000
FROM T
ORDER BY number

Screenshot

18 голосов
/ 06 января 2010

С точки зрения обработки, не имеет значения использовать varchar (8000) против varchar (500). Это скорее «хорошая практика», чтобы определить максимальную длину, которую должно содержать поле, и сделать ваш varchar такой длины. Это то, что может быть использовано для проверки данных. Например, сокращение штата должно состоять из 2 символов или почтового индекса, состоящего из 5 или 9 символов. Раньше это было более важным отличием, когда ваши данные взаимодействовали с другими системами или пользовательскими интерфейсами, где длина поля была критической (например, набор данных плоских файлов мэйнфреймов), но в настоящее время я думаю, что это больше привычка, чем что-либо еще.

9 голосов
/ 20 декабря 2013

У больших столбцов есть несколько недостатков, которые немного менее очевидны и могут заметить вас чуть позже:

  • Все столбцы, которые вы используете в INDEX - не должны превышать 900 байт
  • Все столбцы в предложении ORDER BY не могут превышать 8060 байт. Это немного сложно понять, поскольку это относится только к некоторым столбцам. См. Превышен предел размера строки в SQL 2008 R2 )
  • Если общий размер строки превышает 8060 байт, вы получите « разлив страницы » для этой строки. Это может повлиять на производительность (страница является единицей выделения в SQLServer и имеет фиксированный размер 8000 байт + некоторые накладные расходы. Превышение этого значения не будет серьезным, но это заметно, и вам следует избегать его, если вы можете легко)
  • Многие другие внутренние структуры данных, буферы и, что не менее важно, ваши собственные переменные и табличные переменные должны отражать эти размеры. При чрезмерных размерах чрезмерное выделение памяти может повлиять на производительность

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

В вашем примере названий компаний подумайте, где вы можете их отобразить. Есть ли место для 500 символов? Если нет, то нет смысла хранить их как таковые. http://en.wikipedia.org/wiki/List_of_companies_of_the_United_States перечисляет названия некоторых компаний, максимальный размер - около 50 символов. Так что я бы использовал 100 для столбца макс. Может быть, больше похоже на 80.

9 голосов
/ 06 января 2010

Помимо лучших практик (ответ BBlake)

  • Вы получаете предупреждения о максимальном размере строки (8060) байтов и ширине индекса (900 байтов) с DDL
  • DML умрет, если вы превысите эти пределы
  • ANSI PADDING ON - это значение по умолчанию, поэтому вы можете хранить целую загрузку пробелов
2 голосов
/ 06 января 2010

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

Хотя varchar на самом деле не собирается резервировать пространство в базе данных для неиспользуемого пространства, я вспоминаю версии SQL Server, в которых количество строк в базе данных было немного больше, чем некоторое количество байтов (не помню точное количество), и на самом деле выбрасывая любые данные не подходят. Определенное количество этих байтов было зарезервировано для вещей, встроенных в SQL Server.

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