Есть ли преимущество варчара (500) над варчаром (8000)?

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

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

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

Ответ 1

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

Ответ 2

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

Это покрывается SQL Kiwi здесь

Фактический размер хранимых данных не имеет значения - это потенциальный размер.

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

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

Это может иметь большое отрицательное влияние на потребление памяти и производительность

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

Вернемся к самому механизму SQL Server. Аналогичный случай заключается в том, что при вычислении выделения памяти для распределения для операций SORT SQL Server предполагает, что столбцы varchar(x) в среднем потребляют x/2 байта.

Если большинство столбцов varchar полнее, чем это, это может привести к тому, что операции sort разливаться в tempdb.

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

Это описано в части 2 веб-трансляций SQL Workshops Webcast 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

Ответ 3

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

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

Ответ 4

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

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

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

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

Ответ 5

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

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