Есть ли недостатки при использовании nvarchar (MAX)? - PullRequest
321 голосов
/ 29 сентября 2008

В SQL Server 2005 есть какие-либо недостатки, связанные с тем, что все символьные поля должны быть nvarchar (MAX), вместо того, чтобы явно указывать длину, например, NVARCHAR (255)? (Помимо очевидного, что вы не можете ограничить длину поля на уровне базы данных)

Ответы [ 22 ]

3 голосов
/ 08 июня 2009

Одна проблема заключается в том, что если вам приходится работать с несколькими версиями SQL Server, MAX не всегда будет работать. Поэтому, если вы работаете с устаревшими БД или с любой другой ситуацией, которая включает в себя несколько версий, лучше быть очень осторожным.

3 голосов
/ 29 августа 2016

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

Однако есть еще один фактор, который следует учитывать при выборе n / varchar (Max) вместо n / varchar (n). Будут ли данные проиндексированы (например, фамилия)? Поскольку определение MAX считается LOB, то все, что определено как MAX, недоступно для индексации. и без индекса любой поиск, включающий данные в качестве предиката в предложении WHERE, будет принудительно выполняться при сканировании полной таблицы, что является худшей производительностью, которую вы можете получить для поиска данных.

2 голосов
/ 29 апреля 2013

1) SQL-серверу придется использовать больше ресурсов (выделенная память и время процессора) при работе с nvarchar (max) и nvarchar (n), где n - это число, специфичное для поля.

2) Что это означает в отношении производительности?

В SQL Server 2005 я запросил 13 000 строк данных из таблицы с 15 столбцами nvarchar (max). Я неоднократно синхронизировал запросы, а затем изменил столбцы на nvarchar (255) или менее.

Количество запросов до оптимизации в среднем составляло 2,0858 секунды. Запросы после изменения возвращались в среднем за 1,90 секунды. Это было около 184 миллисекунд улучшения базового запроса select *. Это улучшение на 8,8%.

3) Мои результаты совпадают с несколькими другими статьями, в которых указывалось на разницу в производительности. В зависимости от базы данных и запроса процент улучшения может варьироваться. Если у вас не много одновременно работающих пользователей или очень много записей, разница в производительности не будет для вас проблемой. Однако разница в производительности будет увеличиваться по мере увеличения числа записей и одновременных пользователей.

1 голос
/ 08 июня 2009

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

Ядро базы данных намного эффективнее, сохраняя все из хранилища больших двоичных объектов. Чем меньше вы можете ограничить ряд, тем лучше. Чем больше строк вы можете втиснуть в страницу, тем лучше. База данных работает лучше, когда ей требуется меньше страниц.

1 голос
/ 12 ноября 2008

Интересная ссылка: Зачем использовать VARCHAR, когда вы можете использовать TEXT?

Речь идет о PostgreSQL и MySQL, поэтому анализ производительности отличается, но логика «явности» все еще сохраняется: зачем заставлять себя всегда беспокоиться о чем-то, что актуально в течение небольшого процента времени? Если вы сохранили адрес электронной почты в переменной, вы бы использовали «строку», а не «строку, ограниченную 80 символами».

1 голос
/ 29 сентября 2008

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

1 голос
/ 30 сентября 2016

Мои тесты показали, что при выборе есть различия.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;
1 голос
/ 08 июня 2009

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

0 голосов
/ 29 сентября 2008

Это вызовет проблемы с производительностью, хотя может никогда не вызвать реальных проблем, если ваша база данных мала. Каждая запись будет занимать больше места на жестком диске, и базе данных потребуется считывать больше секторов диска, если вы просматриваете много записей одновременно. Например, небольшая запись может вписать 50 в сектор, а большая запись может уместиться в 5. Вы должны прочитать в 10 раз больше данных с диска, используя большую запись.

0 голосов
/ 17 апреля 2012

Главный недостаток, который я вижу, это то, что, скажем, у вас есть:

Какой из них дает вам больше информации о данных, необходимых для пользовательского интерфейса?

Это

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Или это?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...