Есть ли проблема с созданием всех строковых столбцов Sql Server 2008 varchar (max)? Мои допустимые размеры строк управляются приложением. База данных должна просто сохранять то, что я ей даю. Удастся ли я получить удар производительности, объявив все столбцы строк типа varchar (max) в Sql Server 2008, независимо от того, какой размер данных действительно входит в них?
Varchar (max) везде?
Ответ 1
Используя VARCHAR(MAX)
, вы в основном говорите, что SQL Server "сохраняет значения в этом поле, как вы видите лучше", тогда SQL Server будет выбирать, хранить ли значения как обычный VARCHAR
или как объект большой (Large), В общем случае, если хранимые значения меньше 8000 байт, SQL Server будет обрабатывать значения как обычный тип VARCHAR
.
Если сохраненные значения слишком велики, то столбцу разрешено пролистывать страницу на страницы большого объекта, точно так же, как и для других типов больших объектов (text
, ntext
и image
) - если это произойдет то для чтения данных, хранящихся на дополнительных страницах, требуется чтение дополнительных страниц (т.е. есть производительность пениса), однако это происходит только при слишком больших значениях.
Фактически в SQL Server 2008 или более поздних версиях данные могут переполняться на дополнительные страницы даже с использованием типов данных фиксированной длины (например, VARCHAR(3,000)
), однако эти страницы называются страницами данных переполнения строк и обрабатываются несколько иначе.
Краткая версия: с точки зрения хранения нет недостатка в использовании VARCHAR(MAX)
над VARCHAR(N)
для некоторого N
.
(Обратите внимание, что это также относится к другим типам полей переменной длины NVARCHAR
и VARBINARY
)
FYI - You не может создавать индексы в столбцах VARCHAR(MAX)
Ответ 2
Индексы не могут превышать 900 байтов для одного. Таким образом, вы, вероятно, никогда не сможете создать индекс. Если ваши данные меньше 900 байт, используйте varchar (900).
Это один недостаток: потому что он дает
- действительно плохой результат поиска
- нет уникальных ограничений
Ответ 3
Симон Сабин написал сообщение об этом некоторое время назад. У меня нет времени, чтобы схватить его сейчас, но вы должны его искать, потому что он приходит к выводу, что вы не должны использовать varchar (max) по умолчанию.
Отредактировано: Simon получил несколько сообщений о varchar (max). Ссылки в комментариях ниже показывают это довольно хорошо. Я думаю, что наиболее значимым является http://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspx, в котором говорится о влиянии varchar (max) на кэширование плана. Общий принцип - быть осторожным. Если вам не нужно, чтобы он был максимальным, тогда не используйте max - если вам нужно больше 8000 символов, то обязательно... пойдите для него.
Ответ 4
Для этого вопроса конкретно несколько моментов, о которых я не упоминал.
- В 2005/2008/2008 R2, если столбец LOB включен в индекс, это блокирует перестроения онлайн-индексов.
- В 2012 году ограничение по восстановлению онлайн-индекса отменяется, но столбцы LOB не могут участвовать в новых функциях Добавление NOT NULL Columns в качестве онлайн-операции.
- Замки могут быть удалены дольше в строках, содержащих столбцы этого типа данных. (подробнее)
В моем ответе мы рассмотрим пару других причин: почему бы не varchar(8000)
везде.
- Ваши запросы могут в конечном итоге запросить огромные гранты памяти, не оправданные размером данных.
- В таблице с триггерами она может предотвратить оптимизацию, когда теги версий не добавляются.
Ответ 5
Я задал подобный вопрос раньше. получили интересные ответы. проверьте здесь Был один сайт, в котором парень говорил о вреде использования широких столбцов, однако, если ваши данные ограничены в приложении, мое тестирование опровергло его. Тот факт, что вы не можете создавать индексы в столбцах, означает, что я не буду использовать их все время (лично я бы не использовал их так много, но я немного пурист в этом отношении). Однако, если вы знаете, что в них мало хранится, я не думаю, что они такие плохие. Если вы производите сортировку по столбцам набора записей с varchar (max) в нем (или любой большой столбец, являющийся char или varchar), тогда вы можете понести штрафы за производительность. они могут быть разрешены (если требуется) индексами, но вы не можете поместить индексы на varchar (max). Если вы хотите в будущем доказательство своих столбцов, почему бы просто не привести их к чему-то разумному. например, столбец имен должен составлять 255 символов, а не max... что-то вроде этого.
Ответ 6
В идеале вы должны разрешать только то, что вам нужно. Если вы уверены, что конкретный столбец (например, столбец имени пользователя) не будет длиннее 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 байтам для этих столбцов?
Ответ 7
Есть еще одна причина избежать использования varchar (max) для всех столбцов. По той же причине мы используем контрольные ограничения (чтобы избежать заполнения таблиц нежелательным программным обеспечением или пользовательскими записями), мы хотели бы защитить от любого неисправного процесса, который добавляет гораздо больше данных, чем предполагалось. Например, если кто-то или что-то попытался добавить в поле Сити 3000 байт, мы наверняка знали бы, что что-то не так, и хотели бы остановить процесс мертвым на своих дорожках, чтобы отладить его как можно раньше. Мы также знали бы, что название 3000-байтного города не может быть действительным и будет испортить отчеты и, если мы попытаемся его использовать.