programing

항상 nvarchar(MAX)를 사용할 경우 단점이 있습니까?

powerit 2023. 4. 8. 09:50
반응형

항상 nvarchar(MAX)를 사용할 경우 단점이 있습니까?

SQL Server 2005에서는 nvarchar(255)와 같이 모든 문자 필드를 명시적으로 지정하지 않고 nvarchar(MAX)로 하는 단점이 있습니까? (데이터베이스 수준에서 필드 길이를 제한할 수 없다는 명백한 단점 이외)

MSDN 포럼에서도 같은 질문이 있었습니다.

첫 번째 투고부터 (자세한 내용은 이쪽):

데이터를 VARCHAR(N) 열에 저장하는 경우 값은 물리적으로 동일한 방식으로 저장됩니다.그러나 VARCHAR(MAX) 열에 저장하면 화면 뒤에서 데이터가 TEXT 값으로 처리됩니다.따라서 VARCHAR(MAX) 값을 처리할 때는 몇 가지 추가 처리가 필요합니다.(사이즈가 8000을 초과하는 경우에만 해당)

VARCHAR(MAX) 또는 NVARCHAR(MAX)는 '큰 값 유형'으로 간주됩니다.큰 값 유형은 보통 'out of row'로 저장됩니다.즉, 데이터 행에 '큰 값'이 저장된 다른 위치에 대한 포인터가 있음을 의미합니다.

승인된 답변에 제공된 링크에 따라 다음과 같이 표시됩니다.

  1. nvarchar(MAX) 이내로 됩니다.nvarchar(100)필드 - 데이터가 인라인에 저장되며 'out of row' 데이터 읽기 및 쓰기 오버헤드가 발생하지 않습니다.츠미야

  2. 크기가 4000보다 크면 데이터가 자동으로 '행 밖으로' 저장됩니다.그러니 거기에서도 걱정하지 마세요.

하지만...

  1. 수 .nvarchar(MAX) 을 사용할 수 질의 시키기 위해 수는 .전체 텍스트 색인을 사용할 수 있지만 질의 성능을 향상시키기 위해 열에 색인을 만들 수는 없습니다.이것은 거래를 확정짓는 것입니다.nvarchar(MAX)를 사용합니다.

결론:

수 시간을 의 " 길이 " "를 사용할 수 .nvarchar(4000)

그것은 공정한 질문이고 그는 명백한 것 말고도 진술했다…

단점은 다음과 같습니다.

성능의 영향 쿼리 최적화 도구는 필드 크기를 사용하여 가장 효율적인 Excection 계획을 결정합니다.

1. 데이터베이스의 공간 할당과 페이지는 유연합니다.따라서 업데이트를 사용하여 필드에 정보를 추가할 때 새 데이터가 이전에 삽입된 데이터보다 길면 데이터베이스가 포인터를 생성해야 합니다.이로 인해 데이터베이스 파일이 단편화 = 인덱스부터 삭제, 업데이트 및 삽입에 이르기까지 거의 모든 부분에서 성능이 저하됩니다.http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

통합에 관한 영향 - 다른 시스템이 데이터베이스와의 통합 방법을 알기 어려운 예측 불가능한 데이터 증가 가능성이 있는 보안 문제 모든 디스크 공간을 차지하여 시스템이 크래시 될 수 있습니다.

여기 좋은 기사가 있습니다.http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html

경우에 따라서는 데이터 유형이 데이터 내의 데이터에 대해 어느 정도 인식을 적용하기를 원할 수 있습니다.

예를 들어, 20자보다 길면 안 되는 열이 있다고 가정해 보십시오.이 열을 VARCHAR(MAX)로 정의하면 일부 악성 응용 프로그램에서 긴 문자열을 삽입할 수 있으며 사용자가 전혀 알지 못하거나 방지할 수 없습니다.

다음에 응용 프로그램에서 이 문자열을 사용할 때 문자열의 길이가 해당 문자열이 나타내는 도메인에 대해 적당하고 적절하다고 가정하면 예측 불가능하고 혼란스러운 결과가 발생합니다.

http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx에서 몇 가지 기사를 확인하고 유용한 테스트 스크립트를 찾았습니다.그리고 NVARCHAR(10)와 NVARCHAR(4000)를 비교하도록 변경했습니다.지정된 수치를 사용할 때는 속도 차이가 없지만 MAX를 사용할 때는 속도 차이가 없습니다.직접 테스트할 수 있습니다.이게 도움이 되길 바라.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO

그냥 또 다른 안전 수준이라고 생각하시면 됩니다.완전히 유효한 외부 키 관계 없이 테이블을 설계할 수 있으며 비즈니스 계층에 관련된 엔티티가 완전히 존재하는지 확인할 수 있습니다.단, 외부 키는 비즈니스 계층에서 문제가 발생할 경우에 대비하여 다른 제약 수준을 추가하기 때문에 좋은 설계 관행으로 간주됩니다.필드 크기 제한 및 varchar MAX 미사용도 마찬가지입니다.

최대 또는 텍스트 필드를 사용하지 않는 이유는 SQL Server Enterprise Edition을 사용하더라도 온라인 인덱스 재구성을 수행할 수 없기 때문입니다.

SQL Server 2019 현재 NVARCHAR(MAX)는 인로우 데이터 스토리지를 사용하여 저장되는 경우에도 SCSU "유니코드 압축"지원하지 않습니다.SCSU는 SQL Server 2008에서 추가되었으며 ROW/PAGE 압축 테이블 및 인덱스에 적용됩니다.

따라서 NVARCHAR(MAX)는 동일한 텍스트+ 내용을 가진 NVARCHAR(1.4000) 필드보다 최대 2배의 물리 디스크 공간사용할 수 있습니다(LOB에 저장되지 않은 경우에도).비 SSU 낭비는 표시되는 데이터와 언어에 따라 달라집니다.

Unicode 압축 구현:

SQL Server는 Standard Compression Scheme for Unicode(SCSU) 알고리즘을 구현하여 행 또는 페이지 압축 개체에 저장된 Unicode 값을 압축합니다.이러한 압축 객체의 경우, 유니코드 압축은 nchar(n) 및 nvarchar(n) 열에 대해 자동으로 이루어집니다(nvarchar(max)에서는 사용되지 않습니다).

한편, PAGE 압축(2014년 이후)은 NVARCHAR(MAX) 이 In-Row 데이터로 작성된 경우에도 여전히 적용된다.SCSU의 부족은 '최적화 누락'처럼 느껴집니다.SCSU와 달리 페이지 압축 결과는 공유 선두 프레픽스(복제값)에 따라 크게 다를 수 있습니다.

단, 암묵적인 변환을 회피하기 때문에 OPENJSON 등의 기능으로 I/O 비용이 높아도 NVARCHAR(MAX)를 사용하는 것이 더 빠를 수 있습니다.이는 상대적인 사용 비용과 필터링 전 또는 후에 필드를 터치하는지에 따라 암묵적인 변환 오버헤드가 달라집니다.VARCHAR(MAX) 열에서 2019년 UTF-8 조회를 사용할 때도 이와 동일한 변환 문제가 발생합니다.

또한 NVARCHAR(1-4000)을 사용하려면 최대 8000바이트 행 할당량의 N*2바이트가 필요한데 반해 NVARCHAR(MAX)는 24바이트만 필요합니다.구체적인 구현 세부사항을 고려하기 위해 전체적인 설계와 사용법을 함께 고려해야 합니다.

데이터베이스/데이터/스키마에서는 2개의 열(읽기 시 결합)을 사용하여 디스크 공간 사용을 40%까지 줄이면서도 오버플로우 텍스트 값을 지원할 수 +있었습니다.SCSU는 단점도 있지만 Unicode를 공간 효율적으로 저장할 수 있는 놀랍도록 영리하고 활용도가 낮은 방법입니다.

유일한 문제는 SQL Server 2005에서 애플리케이션을 개발한다는 것입니다.또한 SQL Server 2000을 지원해야 하는 경우도 있습니다.SQL Server 2000은 varchar 또는 nvarchar의 MAX 옵션을 좋아하지 않는다는 사실을 방금 알게 되었습니다.

필드가 설정된 범위(예: 5~10 문자)에 있을 경우 잘못된 생각입니다.길이가 어떻게 될지 확실하지 않으면 max만 쓸 것 같아요.예를 들어 전화번호는 특정 문자수를 넘지 않습니다.

표의 모든 필드의 대략적인 길이 요건에 대해 그렇게 잘 모르겠다고 솔직히 말할 수 있습니까?

무슨 말인지 알겠어요. varchar(max)를 사용하는 것이 좋습니다.

흥미롭게도 MSDN 문서는 다음과 같이 요약하고 있습니다.

열 데이터 항목의 크기가 크게 다를 경우 varchar를 사용하십시오.열 데이터 엔트리의 크기가 크게 달라 크기가 8,000바이트를 초과할 수 있는 경우 varchar(max)를 사용합니다.

여기서 그 문제에 대한 흥미로운 논의가 있다.

데이터베이스의 작업은 기업에서 사용할 수 있도록 데이터를 저장하는 것입니다.그 데이터를 유용하게 만드는 것의 일부는 그것이 의미 있는 것임을 확인하는 것입니다.이름을 입력할 수 있는 글자 수를 제한하지 않는 것은 의미 있는 데이터를 보장하지 않습니다.

이러한 제약을 비즈니스 계층에 구축하는 것은 좋지만, 그렇다고 해서 데이터베이스가 그대로 유지되는 것은 아닙니다.데이터 규칙을 위반하지 않도록 보장하는 유일한 방법은 데이터베이스에서 가능한 한 낮은 수준에서 규칙을 적용하는 것입니다.

위에서 지적한 바와 같이, 이는 주로 스토리지와 성능의 균형입니다.적어도 대부분의 경우엔요.

단, n/varchar(n)보다 n/varchar(Max)를 선택할 때 고려해야 할 다른 요인이 적어도1개 있습니다.데이터가 인덱스화됩니까(예: 성)?MAX 정의는 LOB로 간주되기 때문에 MAX로 정의된 것은 인덱스에 사용할 수 없습니다.인덱스가 없으면 WHERE 절의 술어로 데이터를 포함하는 룩업이 강제로 전체 테이블 검색에 포함되므로 데이터 검색에 대해 얻을 수 있는 성능 중 가장 좋지 않습니다.

한 가지 문제는 여러 버전의 SQL Server를 사용해야 하는 경우 MAX가 항상 작동하지 않는다는 것입니다.따라서 레거시 DB 또는 여러 버전이 관련된 다른 상황에서 작업할 경우 매우 주의해야 합니다.

1) nvarchar(max)와 nvarchar(n)를 처리할 때 SQL Server는 더 많은 리소스(할당된 메모리 및 CPU 시간)를 사용해야 합니다.여기서 n은 필드 고유의 수치입니다.

2) 퍼포먼스에 대해서 이것은 무엇을 의미합니까?

SQL Server 2005에서는 15개의 nvarchar(max) 열이 있는 테이블에서 13,000줄의 데이터를 조회했습니다.몇 번이고 쿼리의 타이밍을 재어 컬럼을 nvarchar(255) 이하로 변경했습니다.

최적화 전의 쿼리는 평균 2.0858초였습니다.변경 후 쿼리는 평균 1.90초 만에 반환되었습니다.이는 기본 선택 * 쿼리가 약 184밀리초 향상되었습니다.그것은 8.8%의 개선이다.

3) 제 결과는 성능 차이가 있음을 나타내는 다른 몇 가지 기사와 일치합니다.데이터베이스 및 쿼리에 따라 개선률이 달라질 수 있습니다.동시 사용자가 많지 않거나 레코드가 많지 않은 경우 성능 차이는 문제가 되지 않습니다.그러나 더 많은 기록과 동시 사용자가 증가할수록 성능 차이는 더 커집니다.

스트링을 패딩하여 출력을 varchar(max)로 하는 udf가 있었습니다.조정되는 기둥의 적절한 크기로 주조하지 않고 직접 사용하면 성능이 매우 저하되었습니다.결국 udf의 모든 발신자에게 스트링을 더 작은 크기로 재캐스팅하는 대신 큰 음표로 임의의 길이로 udf를 설정했습니다.

레거시 시스템 지원데이터를 사용하는 시스템이 있고 특정 길이로 예상되는 경우, 데이터베이스는 길이를 적용하기에 적합한 위치입니다.이것은 이상적이지 않지만 레거시 시스템은 이상적이지 않을 수 있습니다.=P

한 행의 모든 데이터(모든 열에 대해)가 8000자 이하의 문자를 사용할 수 없는 경우 데이터 레이어 설계에서 이를 적용해야 합니다.

데이터베이스 엔진은 모든 데이터를 BLOB 스토리지에 보관하지 않도록 훨씬 더 효율적입니다.행을 작게 제한할수록 좋습니다.한 페이지에 더 많은 행을 넣을수록 좋습니다.데이터베이스는 액세스해야 하는 페이지 수가 적을 때 성능이 향상됩니다.

제 테스트 결과 선택 시 차이가 있는 것으로 나타났습니다.

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;

대상 링크:TEXT를 사용할 수 있는데 VARCHAR을 사용하는 이유는 무엇입니까?

Postgre에 대해서입니다.SQL과 MySQL은 성능 분석이 다르지만 "명확성"에 대한 논리는 여전히 유효합니다.왜 당신은 항상 적은 시간 동안 관련된 것에 대해 고민하도록 강요합니까?전자 메일 주소를 변수에 저장한 경우 '80자로 제한된 문자열'이 아닌 '문자열'을 사용합니다.

가장 큰 단점은 다음과 같습니다.

UI에 필요한 데이터에 대해 가장 많은 정보를 제공하는 것은 무엇입니까?

이것.

            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]

단점 중 하나는 예측 불가능한 변수를 중심으로 설계하기 때문에 행, 페이지 및 익스텐트로 구성된 내부 SQL Server 데이터 구조를 이용하는 대신 무시하는 것입니다.

따라서 C의 데이터 구조 정렬에 대해 생각하게 됩니다. 정렬을 인식하는 것은 일반적으로 좋은 것으로 간주됩니다. 비슷한 아이디어와 다른 컨텍스트입니다.

페이지익스텐트의 MSDN 페이지

Row-Overflow 데이터용 MSDN 페이지

처음에는 이런 생각을 했지만, 그 다음에 다시 생각했어요.퍼포먼스에 대한 영향이 있지만 필드의 실제 크기를 파악할 수 있는 문서로도 사용할 수 있습니다.데이터베이스가 대규모 에코시스템에 배치되어 있는 경우에도 마찬가지입니다.내 생각에 관용을 베풀되 합리적인 범위 내에서만 관용을 베풀어야 한다.

비즈니스 및 데이터 레이어 로직 문제에 대한 저의 생각은 다음과 같습니다.DB가 비즈니스 로직을 공유하는 시스템 간의 공유 리소스인 경우 당연히 이러한 로직을 적용하는 것이 당연하다고 생각되지만, 이를 위한 최선의 방법은 API를 제공하는 것입니다. 이를 통해 상호 작용을 테스트하고 비즈니스 로직을 소속된 위치에서 유지하며 시스템을 분리할 수 있습니다.계층이 분리된 상태로 유지됩니다.그러나 데이터베이스가 하나의 애플리케이션만 지원해야 하는 경우, 현재 올바른 것은 무엇인가?라는 생각을 통해 민첩성을 확보해 보겠습니다.이러한 액세스가 필요한 경우 해당 데이터에 API를 제공합니다.

물론 이것이 이상적입니다.기존 시스템으로 작업하고 있다면 적어도 단기적으로는 다른 방법으로 작업해야 할 가능성이 높습니다.

이로 인해 성능 문제가 발생하지만 데이터베이스가 작을 경우 실제 문제가 발생하지 않을 수 있습니다.한 번에 많은 레코드를 검색할 경우 각 레코드는 하드 드라이브에서 더 많은 공간을 차지하고 데이터베이스는 디스크의 더 많은 섹터를 읽어야 합니다.예를 들어, 작은 레코드는 섹터에 50개, 큰 레코드는 5개일 수 있습니다.대용량 레코드를 사용하려면 디스크에서 10배 더 많은 데이터를 읽어야 합니다.

컨트롤의 폭을 예측할 수 없게 되어 화면 설계가 어려워집니다.

언급URL : https://stackoverflow.com/questions/148398/are-there-any-disadvantages-to-always-using-nvarcharmax

반응형