programing

varchar와 nvarchar SQL Server 데이터 유형의 주요 성능 차이는 무엇입니까?

i4 2023. 4. 21. 20:13
반응형

varchar와 nvarchar SQL Server 데이터 유형의 주요 성능 차이는 무엇입니까?

는 학교에서 웹 앱 SQL Server 2005.
나는 of ......의 문제에 몇 .의 문제에 대해 몇 개의 학파를 본다.varchar »nvarchar:

  1. varchar 한, '된 데이터'를 합니다.nvarchar.
  2. 쓰세요.nvarchar모든 것을 위해.

나는 2번 관점의 장점을 보기 시작했다.nvarchar가 2배의 공간을 차지한다는 것은 알지만, 수백 명의 학생만 데이터를 저장할 수 있기 때문에 큰 문제는 아닙니다.저는 걱정하지 말고 모든 것이 nvarchar를 사용하도록 하는 것이 가장 쉬울 것 같습니다.아니면 제가 놓친 게 있나요?

디스크 공간이 문제가 아닙니다...메모리와 퍼포먼스는 그럴 겁니다.페이지 읽기 두 배, 인덱스 크기 두 배, 이상한 LIKE 및 = 지속적인 동작 등

중국어 등의 스크립트를 저장해야 합니까?네, 아니오...

또한 MS BOL "Unicode의 스토리지성능 영향"에서

편집:

nvarchar의 퍼포먼스가 얼마나 나쁠 수 있는지를 나타내는 최근의 SO 질문...

SQL Server는 nvarchar 문자열 내에서 검색할 때 높은 CPU를 사용합니다.

항상 nvarchar를 사용하십시오.

대부분의 응용 프로그램에서는 더블바이트 문자가 필요하지 않을 수 있습니다.그러나 더블바이트 언어를 지원해야 하고 데이터베이스 스키마에서 싱글바이트만 지원한다면 애플리케이션 전체를 다시 수정하는 것은 매우 비용이 많이 듭니다.

한 애플리케이션을 varchar에서 nvarchar로 마이그레이션하는 데 드는 비용은 대부분의 애플리케이션에서 사용하는 추가 Disk 공간보다 훨씬 높습니다.

일관되게! VARCHAR에 VARCHAR에 가입하면 퍼포먼스가 크게 향상됩니다.

nvarchar는 메모리, 스토리지, 작업 세트 및 인덱싱에서 상당한 오버헤드를 발생시키므로 사양에 따라서는 전혀 필요하지 않다고 명시되어 있으면 신경 쓰지 마십시오.

"항상 nvarchar" 규칙은 많은 상황에서 완전히 낭비될 수 있기 때문에 하드하고 빠른 "항상 nvarchar" 규칙은 없습니다.특히 ASCII/EBCDIC의 ETL이나 대부분의 경우 키와 외부 키인 식별자 및 코드 열입니다.

한편, 칼럼의 경우는 많이 있기 때문에, 이 질문은 일찌감치 할 수 있고, 즉석에서 어려운 답변을 얻지 못했다면, 칼럼 nvarchar로 하겠습니다.

이미 몇 가지 답변이 있기 때문에, 여기에 또 다른 답변을 덧붙이는 것은 망설여집니다만, 몇 가지 요점은 아직 정해지지 않았거나 명확하지 않은 것입니다.

첫 번째: 항상 사용하지 않음NVARCHAR이는 매우 위험하고 비용이 많이 드는 태도/접근법입니다.커서는 특정 문제를 해결하는 가장 효율적인 수단이기도 하고 일반적인 회피책이기도 하기 때문에 "커서는 사용하지 않는다"고 말하는 것이 더 나을 수 없습니다.WHILE루프는 거의 항상 올바르게 수행된 커서보다 느립니다.

"항상"이라는 용어를 사용해야 할 때는 "항상 상황에 가장 적합한 일을 하라"고 조언할 때뿐입니다.단기간에 얻을 수 있는 개발 시간(매니저: "지금까지 몰랐던 이 기능이 필요합니다!")과 장기 유지 보수 비용(처음에는 3개월의 프로젝트를 3주간의 전력 질주로 완료하도록 팀에 압력을 가했던 매니저)의 균형을 맞추려고 할 때는 특히 이 점을 판단하기가 어렵습니다.왜 이런 퍼포먼스 문제가 생기는 거죠?유연성이 없는 X를 어떻게 할 수 있었을까?이걸 고치려면 전력질주나 두 번 할 여유가 없어우선 사항으로 돌아가기 위해 일주일 안에 무엇을 할 수 있을까요?그리고 이런 일이 계속 발생하지 않도록 디자인에 더 많은 시간을 할애해야 합니다!)

번째: @gbn의 답변은 경로가 100% 명확하지 않을 때 특정 데이터 모델링 결정을 내릴 때 고려해야 할 매우 중요한 몇 가지 사항을 다루고 있습니다.그러나 고려해야 할 점은 다음과 같습니다.

  • 트랜잭션 로그 파일 크기
  • 복제에 걸리는 시간(복제를 사용하는 경우)
  • ETL에 걸리는 시간(ETLing의 경우)
  • 원격 시스템으로 로그를 전송하고 복원하는 데 걸리는 시간(로그 전달을 사용하는 경우)
  • 백업 크기
  • 백업을 완료하는 데 걸리는 시간
  • restore에 걸리는 시간(이것이 언젠가 중요해질지도 모른다;-)
  • tempdb에 필요한 크기
  • 트리거 성능(tempdb에 저장된 삽입 및 삭제된 테이블의 경우)
  • 행 버전 관리 성능(버전 저장소가 tempdb이기 때문에 스냅샷 격리를 사용하는 경우)
  • CFO가 작년에 SAN에 100만달러를 지출했기 때문에 스토리지 추가에 25만달러를 승인하지 않을 경우 새로운 디스크 공간을 확보할 수 있습니다.
  • INSERT 및 UPDATE 작업을 수행하는 데 걸리는 시간
  • 인덱스 유지 관리를 수행하는 데 걸리는 시간

공간 낭비는 시스템 전체에 캐스케이드 효과를 가져옵니다.나는 이 주제에 대해 명확한 세부사항을 설명하는 기사를 썼다.디스크는 싸다! ORLY? (무료 등록 필요, 죄송하지만 저는 그 정책을 통제할 수 없습니다.)

셋째: "이것은 작은 앱"이라는 측면에 초점을 맞춘 답변도 있고, "적절한 것을 사용하라"고 올바르게 제안하는 답변도 있지만, O.P.에 진정한 지침을 제공하는 답변은 없습니다.질문에서 언급된 중요한 세부 사항은 이것이 그들의 학교를 위한 웹 페이지라는 것입니다.좋습니다! 그럼 다음 사항을 제안해 보겠습니다.

  • 학생 및/또는 교직원 이름 필드는 다음과 같아야 합니다.NVARCHAR왜냐하면, 시간이 흐르면서, 다른 문화권에서 온 이름들이 그 장소들에 나타날 가능성이 점점 더 커지기 때문이다.
  • 지만만 주소 ?? ????되어 있지 ).레코드가 에되어 있다고 하고, 합니다.VARCHAR적절한 코드 페이지(필드 조합에서 결정)를 지정합니다.
  • 또는 코드를 (ISO 코드를 저장할 가 없음)INTTINYINT수 길이,를 사용합니다.CHAR(2)와 「」의 .CHAR(3)3월 3일 '다'와 바이너리 .Latin1_General_100_BIN2.
  • 번호 번호 를 보존하는 는, 「우편 번호」를 합니다.VARCHARA-Z 이외에는 어떤 문자도 사용하지 않는 것이 국제 표준이기 때문입니다. ,, 직, 직을 사용하세요.VARCHAR우편번호가 숫자가 아니기 때문에 INT가 아닌 US 우편번호만 저장해도 문자열이며 선두에 0이 있는 것도 있습니다. '다'와 바이너리 .Latin1_General_100_BIN2.
  • 는, 「/」URL 를 합니다.NVARCHAR두 문자 모두 유니코드 문자를 포함할 수 있기 때문입니다.
  • 기타 등등...

넷째: 현재 고객님은NVARCHAR 배 하는 데이터입니다.VARCHAR("잘 들어맞는" =는 "?"로 바뀌지 않습니다.) 그리고 어찌된 일인지 애플리케이션이 마법처럼 커졌고 이제 대부분의 행이 표준 ASCII이지만 일부 행은 유니코드 문자를 포함하므로 수백만 개의 레코드가 있습니다.NVARCHAR이치노

  1. SQL Server 2008 - 2016 RTM을 사용하고 Enterprise Edition에 있는 경우 또는 SQL Server 2016 SP1(모든 에디션에서 데이터 압축을 사용할 수 있게 됨) 이상을 사용하는 경우 데이터 압축을 실행할 수 있습니다.데이터 압축은 Unicode 데이터를 압축할 수 있습니다('항상'은 아닙니다.NCHAR ★★★★★★★★★★★★★★★★★」NVARCHAR[ ]이렇게 하다결정 요인은 다음과 같습니다.

  2. NCHAR(1 - 4000) ★★★★★★★★★★★★★★★★★」NVARCHAR(1 - 4000)Unicode에는 표준 압축 방식을 사용하지만 SQL Server 2008 R2부터 시작하여 IN ROW 데이터에만 적용되며 OFLOW는 사용되지 않습니다. 이는 일반 ROW/PAGE 압축 알고리즘보다 나은 것으로 보입니다.

  3. NVARCHAR(MAX) ★★★★★★★★★★★★★★★★★」XML ()VARBINARY(MAX),TEXT , , , , 입니다.NTEXT) IN ROW 데이터(LOB 페이지 또는 OFLOW 페이지에서 행이 아닌 데이터)는 적어도 PAGE 압축은 수 있지만 ROW 압축은 할 수 없습니다.물론 PAGE 압축은 연속된 값의 크기에 따라 달라집니다.VARCHAR(MAX)로 테스트한 결과 6000자/바이트 행은 압축되지 않지만 4000자/바이트 행은 압축되었습니다.

  4. OFF ROW 데이터, LOB 또는 OVERLOW = 압축 기능 없음!

  5. Enterprise Edition이 아닌 SQL Server 2005 또는 2008 - 2016 RTM을 사용하는 경우 다음 두 개의 필드를 사용할 수 있습니다.VARCHAR 1개의 ★★★★★★★★★★★★★★.NVARCHAR 대부분 ASCII 0이며, ASCII 문자(값 0~127)에 URL을 VARCHAR, 유니코드할 수 있습니다.스키마에는 다음 3개의 필드를 포함할 수 있습니다.

       ...
       URLa VARCHAR(2048) NULL,
       URLu NVARCHAR(2048) NULL,
       URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
       CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
                         ([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
                     AND ([URLa] IS NULL OR [URLu] IS NULL))
     );
    

    이 모델에서 선택할 수 있는 것은[URL]삽입되는지 여부를 어떤 합니다. 이 입력 .NVARCHAR 삭제:

     INSERT INTO TableName (..., URLa, URLu)
     VALUES (...,
             IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
             IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
            );
    
  6. 는, 「GZIP」으로 할 수 .VARBINARY(MAX)다음과 같이 합니다.

    • SQL Server 2005 - 2014의 경우: SQLCLR을 사용할 수 있습니다.SQL #(제가 작성한 SQLCLR 라이브러리)에는 Util_가 포함되어 있습니다.GZip유틸리티_무료 버전의 GUnzip
    • : SQL Server 2016을 할 수 .COMPRESS ★★★★★★★★★★★★★★★★★」DECOMPRESSGZIP에 의한 것입니다.
  7. SQL Server 2017 이상을 사용하는 경우 테이블을 클러스터된 열 저장소 인덱스로 만들 수 있습니다.

  8. 에 대한 지원이 Server 2019에 되었습니다.VARCHARCHAR데이터형현재 너무 많은 버그가 있어 사용할 수 없습니다.단, 버그가 수정되어 있는 경우는 경우에 따라서는 이 옵션이 선택됩니다.이 새로운 기능에 대한 자세한 분석은 "Native UTF-8 Support in SQL Server 2019: Savior or False Propect?"라는 제 게시물을 참조하십시오.

당신의 어플리케이션은 데이터베이스 크기가 작기 때문에 nvarchar로 괜찮습니다."항상 nvarchar를 사용한다"는 말은 지나치게 단순하다.한자 등 엉뚱한 문자를 저장할 필요가 없다면 VARCHAR을 사용하면 공간을 많이 절약할 수 있습니다.제 현직에 있던 전임자는 NVARCHAR를 사용하여 불필요할 때 설계했습니다.최근에 VARCHAR로 전환하여 해당 테이블에서만 15GB를 절약했습니다(고도의 쓰기 대상).또한 테이블에 인덱스가 있고 해당 열을 포함하거나 복합 인덱스를 만들려면 인덱스 파일 크기를 더 크게 만들면 됩니다.

신중하게 판단해 주세요.SQL 개발 및 데이터 정의에서는 (물론 어떤 대가를 치르더라도 커서를 피하는 것 이외에는) "기본 답변"이 거의 없는 것 같습니다.

어플리케이션이 작기 때문에 varchar에 비해 nvarchar를 사용하는 경우 기본적으로 비용이 크게 증가하지 않으며 Unicode 데이터를 저장해야 하는 경우 향후 발생할 수 있는 문제를 줄일 수 있습니다.

일반적으로 가장 비용이 많이 드는 데이터 유형으로 시작하고 제약이 가장 적습니다.실전에 투입하다.퍼포먼스에 문제가 생기기 시작하면, 그 안에 실제로 무엇이 저장되어 있는지를 확인합니다.nvarchar컬럼을 클릭합니다.안 맞는 요?varchar그렇지 않으면 varchar로 전환합니다.어디가 아픈지 알기 전에 미리 최적화하려고 하지 마세요.nvarchar와 varchar 중 하나를 선택하는 것이 향후 애플리케이션의 속도를 떨어뜨릴 것이라고는 생각하지 않습니다.퍼포먼스 튜닝으로 비용 대비 효과가 크게 향상되는 어플리케이션도 있습니다.

이 프로젝트들은 모두 다국어이기 때문에 지난 몇 년간 모든 프로젝트에 NVARCHAR를 사용했습니다.외부 소스(ASCII 파일 등)에서 가져온 데이터는 데이터베이스에 삽입되기 전에 Unicode로 업 변환됩니다.

큰 인덱스 등에서 퍼포먼스에 관한 문제는 아직 발생하지 않았습니다.인덱스는 메모리를 더 많이 사용하지만 메모리는 저렴합니다.

저장 프로시저를 사용하든 SQL을 즉시 구성하든 모든 문자열 상수 앞에 N이 붙는지 확인합니다(예: SET @foo = N'Hello world). 따라서 이 상수도 유니코드입니다.이렇게 하면 실행 시 문자열 유형 변환이 방지됩니다.

YMMV

수 해 주십시오.nvarchar반드시 필요한 경우를 제외하고 이 데이터 필드 유형은 더 큰 데이터베이스의 성능을 파괴합니다.성능 및 공간 측면에서 문제가 있는 데이터베이스를 상속받았습니다. 수 !30GB 데이터베이스의 크기를 70%까지 줄일 수 있었습니다!이 되는 「 thereifications스를를 there there there there there there there there there there there there there there there there there there」는varchar님의 지원도 컸습니다.100만 개 이 있는 경우 이상의 는 사용하지 .nvarchar무슨 수를 써서라도

저는 직장에서 이 질문에 자주 대응합니다.

  • 인벤토리 및 가격에 대한 FTP 피드 - varchar가 정상적으로 작동했을 때 항목 설명 및 기타 텍스트가 nvarchar로 표시되었습니다.이러한 파일을 varchar로 변환하면 파일 크기가 거의 절반으로 줄어들어 업로드에 큰 도움이 되었습니다.

  • 상기 시나리오는 상품 설명에 특수 문자(상표, 기억나지 않을 수 있음)를 입력할 때까지 정상적으로 동작했습니다.

나는 여전히 varchar를 매번 사용하지 않는다.특수 캐릭터에 대한 의문이나 가능성이 있다면 nvarchar를 사용합니다.필드를 채우는 것을 100% 제어할 때 varchar를 주로 사용합니다.

이 모든 설명에서 UTF-8에 대한 언급이 없었던 이유는 무엇입니까? 완전한 유니코드 범위를 저장할 수 있다고 해서 UNICODE 용어를 사용하기 위해 항상 문자당 2바이트(또는 "코드 포인트")를 할당할 필요는 없습니다.모든 ASCII가 UTF-8입니다.SQL Server는 텍스트가 엄밀한 ASCII(즉, 상위 바이트 비트0)인 VARCHAR() 필드를 체크합니까?아니길 바래.

유니코드를 저장하고 오래된 ASCII 전용 어플리케이션과의 호환성을 원한다면 VARCHAR() 및 UTF-8을 사용하는 것이 가장 좋은 방법이라고 생각합니다.필요할 때만 더 많은 공간을 사용합니다.

UTF-8을 잘 모르시는 분들은 프라이머를 추천합니다.

특정 집합의 문자가 포함되지 않도록 데이터 유형을 의도적으로 제한해야 하는 예외적인 경우가 있습니다.예를 들어, 도메인 이름을 데이터베이스에 저장해야 하는 시나리오가 있었습니다.당시에는 도메인 이름의 국제화를 신뢰할 수 없었기 때문에 기본 수준에서 입력을 제한하고 잠재적인 문제를 방지하는 것이 더 나았습니다.

「 」를 사용하고 NVARCHAR가 그것을로 하는 만으로, 가장 은, 할 수 없는 「이해할 수 없는 것」입니다.sp_executesql에 퍼포먼스의 에서 SQL의 모든 등을 실행하는 것이 VARCHAR 다음, 최종 를 ㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴ다NVARCHAR파라미터에 합니다.항상 ''라고 쓰지 마세요.NVARCHAR!

언급URL : https://stackoverflow.com/questions/35366/what-are-the-main-performance-differences-between-varchar-and-nvarchar-sql-serve

반응형