varchar (max) везде? - PullRequest
       29

varchar (max) везде?

75 голосов
/ 19 января 2010

Есть ли проблема с тем, чтобы все ваши строковые столбцы Sql Server 2008 были varchar (max)? Мои допустимые размеры строк управляются приложением. База данных должна просто сохранять то, что я даю. Буду ли я испытывать снижение производительности, объявляя все строковые столбцы типа varchar (max) в Sql Server 2008, независимо от того, какой размер данных в них фактически идет?

Ответы [ 7 ]

45 голосов
/ 27 июля 2011

Используя VARCHAR(MAX), вы в основном говорите SQL Server «сохранять значения в этом поле, как вам лучше», а затем SQL Server выбирает, сохранять ли значения как обычный VARCHAR или как LOB (большой объект), Как правило, если хранимые значения меньше 8000 байт, SQL Server будет обрабатывать значения как обычный тип VARCHAR.

Если хранимые значения слишком велики, столбцу разрешается разливатьсо страницы на страницы больших объектов, точно так же, как и для других типов больших объектов (text, ntext и image) - если это происходит, то для чтения данных, хранящихся на дополнительных страницах, требуются дополнительные чтения страниц (т. е.производительность невелика), однако это происходит только в том случае, если сохраненные значения слишком велики .

Фактически в SQL Server 2008 или более поздних версиях данные могут перетекать на дополнительные страницы даже с фиксированной длинойтипы данных (например, VARCHAR(3,000)), однако эти страницы называются страницами с данными о переполнении строк и обрабатываются немного по-разному.

Короткая версия: с точки зрения хранения нет недостатка в использовании VARCHAR(MAX) больше VARCHAR(N) для некоторых N.

(Обратите внимание, что это также относится к другим типам полей переменной длины NVARCHAR и VARBINARY)

К вашему сведению - вы не можете создать индексы для VARCHAR(MAX) столбцов

31 голосов
/ 19 января 2010

Индексы не могут иметь ширину более 900 байт для одного. Таким образом, вы, вероятно, никогда не сможете создать индекс. Если ваши данные меньше 900 байт, используйте varchar (900).

Это один недостаток: потому что он дает

  • очень плохая производительность поиска
  • нет уникальных ограничений
9 голосов
/ 19 января 2010

Саймон Сабин написал пост об этом некоторое время назад. У меня нет времени, чтобы взять его сейчас, но вы должны его найти, потому что он приходит к выводу, что вы не должны использовать varchar (max) по умолчанию.

Отредактировано: у Саймона есть несколько постов о varchar (max). Ссылки в комментариях ниже показывают это довольно хорошо. Я думаю, что наиболее значимым является http://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspx,, в котором говорится о влиянии varchar (max) на кэширование плана. Общий принцип - быть осторожным. Если вам не нужно, чтобы он был максимальным, не используйте max - если вам нужно более 8000 символов, тогда обязательно ... продолжайте.

5 голосов
/ 28 декабря 2012

По этому вопросу конкретно несколько пунктов, которые я не вижу упомянутыми.

  1. 2005/2008/2008 R2, если в индекс включен столбец больших объектов, это блокирует перестроения индекса в оперативном режиме.
  2. В 2012 году ограничение на перестроение индекса в сети снято, но столбцы больших объектов не могут участвовать в новой функциональности Добавление столбцов NOT NULL в качестве оперативной операции .
  3. Блокировки могут быть сняты дольше в строках, содержащих столбцы этого типа данных. (* 1 010 * * более 1011 *)

В моем ответе рассмотрены несколько других причин относительно , почему бы не varchar(8000) везде .

  1. В результате ваши запросы могут запрашивать огромные объемы памяти, не оправданные размером данных.
  2. В таблице с триггерами это может предотвратить оптимизацию, когда теги версий не добавляются.
4 голосов
/ 23 августа 2011

Я задавал подобный вопрос ранее.получил несколько интересных ответов.проверить это здесь Был один сайт, на котором парень говорил о вреде использования широких столбцов, однако, если ваши данные ограничены в приложении, мое тестирование опровергло это.Тот факт, что вы не можете создавать индексы для столбцов, означает, что я не буду использовать их все время (лично я бы не стал их использовать вообще, но я немного пурист в этом отношении).Однако, если вы знаете, что в них мало что хранится, я не думаю, что они такие плохие.Если вы выполните какую-либо сортировку по столбцам набора записей с varchar (max) в нем (или любой широкий столбец, представляющий собой char или varchar), то вы можете понести потери производительности.они могут быть разрешены (если требуется) индексами, но вы не можете поместить индексы в varchar (max).Если вы хотите, чтобы ваши колонки были проверены на будущее, почему бы просто не поставить их на что-то разумное.например, имя столбца должно быть 255 символов, а не максимум ... такая вещь.

1 голос
/ 27 апреля 2016

Есть еще одна причина избегать использования varchar (max) для всех столбцов. По той же причине, по которой мы используем проверочные ограничения (чтобы не заполнять таблицы нежелательной информацией, вызванной ошибочным программным обеспечением или пользовательскими записями), мы хотели бы защититься от любого ошибочного процесса, который добавляет гораздо больше данных, чем предполагалось. Например, если кто-то или что-то попытается добавить 3000 байтов в поле City, мы наверняка будем знать, что что-то не так, и захотим остановить процесс как можно быстрее, чтобы отладить его как можно раньше. Мы также знали бы, что 3000-байтовое название города не может быть действительным и может испортить отчеты и тому подобное, если мы попытаемся использовать его.

1 голос
/ 19 января 2010

В идеале вы должны позволять только то, что вам нужно. Это означает, что если вы уверены, что определенный столбец (скажем, столбец с именем пользователя) никогда не будет иметь длину более 20 символов, использование VARCHAR (20) против VARCHAR (MAX) позволяет базе данных оптимизировать запросы и структуры данных.

Из MSDN: http://msdn.microsoft.com/en-us/library/ms176089.aspx

Variable-length, non-Unicode character data. n can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes.

Вы действительно когда-нибудь собираетесь приблизиться к 2 ^ 31-1 байтам для этих столбцов?

...