varchar (8000)보다 varchar (500)의 장점이 있습니까?


90

나는 MSDN 포럼과 여기에서 이것을 읽었으며 아직 명확하지 않습니다. 이것이 맞다고 생각합니다. Varchar (max)는 텍스트 데이터 유형으로 저장되므로 단점이 있습니다. 따라서 귀하의 필드가 8000 자 미만이 될 것이라고 가정 해 보겠습니다. 내 데이터베이스 테이블의 BusinessName 필드와 같습니다. 실제로 비즈니스 이름은 아마도 항상 500 자 미만일 것입니다. 내가 실행하는 많은 varchar 필드가 8k 문자 수에 훨씬 못 미치는 것 같습니다.

그렇다면 해당 필드를 varchar (8000) 대신 varchar (500)으로 만들어야합니까? 내가 이해하는 SQL에서이 둘 사이에는 차이가 없습니다. 따라서 삶을 쉽게 만들기 위해 모든 varchar 필드를 varchar (8000)로 정의하고 싶습니다. 단점이 있습니까?

관련 : varchar 열의 크기 (이 질문에 대한 답이 없다고 생각했습니다).


6
명함에 500 자 길이의 비즈니스 이름을 넣으려고한다고 상상해보십시오 ... :)
OMG Ponies

2
@OMG Ponies : 사용자 이름을 볼 때마다 웃습니다. 자, 뭐라고 하셨어요? (농담)
jcollum

4
@jcollum : SpaceMan Spiff는 항상 내 투표를받습니다. 그것은 사실이 아닙니다. 어떤 Calvin & Hobbes도 할 것입니다. 또는 F-14를 비행하는 티라노사우루스. 하지만 나는 탈선 ...
OMG Ponies

답변:


20

처리 관점에서 varchar (8000)과 varchar (500)을 사용하는 것은 차이가 없습니다. 필드가 보유해야하는 최대 길이를 정의하고 varchar를 그 길이로 만드는 것이 "좋은 방법"에 가깝습니다. 데이터 유효성 검사를 지원하는 데 사용할 수 있습니다. 예를 들어, 주 약자를 2 자로 만들거나 우편 번호를 5 자 또는 9 자로 만듭니다. 이전에는 데이터가 필드 길이가 중요한 다른 시스템 또는 사용자 인터페이스 (예 : 메인 프레임 플랫 파일 데이터 세트)와 상호 작용할 때 더 중요한 구분 이었지만, 요즘에는 다른 무엇보다 습관이 더 많다고 생각합니다.


3
당연히 최대 길이가있는 것들에 대해 말이됩니다. 하지만 최대 길이가 명확하지 않은 경우 어떻게합니까? 예 : 업체명.
jcollum

2
이와 같은 경우, 잠재적으로 크기를 예측할 수있는 방법이 없을 경우 데이터 유형에 따라 보통 varchar (8000) 또는 varchar (max)를 사용합니다
BBlake

4
이것은 2017 년에도 성능에 차이를 만드는 것 같습니다. dba.stackexchange.com/a/162117/1822
a_horse_with_no_name

2
더 최근의 답변 비용 이 있음을 보여 줍니다. 최적화 로직 Martin Smith의 답변에 영향을 미치며 gbnOliver가 언급 한 총 8K 행 크기 문제도 고려 합니다.
ToolmakerSteve

124

이것이 차이를 만들 수있는 한 가지 예는 트리거 이후에 ​​테이블에 행 버전 관리 정보를 추가하지 않는 성능 최적화를 방지 할 수 있다는 것입니다.

여기에서는 SQL Kiwi에서 다룹니다.

저장된 데이터의 실제 크기는 중요하지 않습니다. 중요한 것은 잠재적 인 크기입니다.

마찬가지로 2016 년부터 메모리 최적화 테이블을 사용하는 경우 LOB 열 또는 잠재적으로 인 로우 제한을 초과 할 수 있지만 패널티가있는 열 너비 조합을 사용할 수있었습니다.

(최대) 열은 항상 행 외부에 저장됩니다. 다른 열의 경우 테이블 정의의 데이터 행 크기가 8,060 바이트를 초과 할 수있는 경우 SQL Server는 가장 큰 가변 길이 열을 행 외부로 푸시합니다. 다시 말하지만 여기에 저장하는 데이터의 양에 의존하지 않습니다.

이는 메모리 소비 및 성능에 큰 부정적인 영향을 미칠 수 있습니다.

열 너비를 과도하게 선언하면 큰 차이가 발생할 수있는 또 다른 경우는 테이블이 SSIS를 사용하여 처리되는 경우입니다. 가변 길이 (비 BLOB) 열에 할당 된 메모리는 실행 트리의 각 행에 대해 고정되며 열의 선언 된 최대 길이에 따라 달라지며 이는 메모리 버퍼의 비효율적 인 사용으로 이어질 수 있습니다 (예) . SSIS 패키지 개발자는 소스보다 더 작은 열 크기를 선언 할 수 있지만이 분석은 먼저 수행하고 적용하는 것이 가장 좋습니다.

SQL Server 엔진 자체에서 비슷한 경우는 SORT작업 에 할당 할 메모리 부여를 계산할 때 SQL Server에서 varchar(x)열이 평균적으로 x/2바이트를 소비 한다고 가정하는 것입니다 .

대부분의 varchar열이 그보다 가득 차면 sort작업이 tempdb.

귀하의 경우 varchar열이 8000바이트 로 선언 되었지만 실제로 내용이 훨씬 적은 경우 쿼리에 필요하지 않은 메모리가 할당되며 이는 분명히 비효율적이며 메모리 부여를 기다릴 수 있습니다.

여기에서 다운로드 할 수있는 SQL 워크샵 웹 캐스트 1의 Part 2에서 다루 거나 아래를 참조하십시오.

use tempdb;

CREATE TABLE T(
id INT IDENTITY(1,1) PRIMARY KEY,
number int,
name8000 VARCHAR(8000),
name500 VARCHAR(500))

INSERT INTO  T 
(number,name8000,name500)
SELECT number, name, name /*<--Same contents in both cols*/
FROM master..spt_values

SELECT id,name500
FROM T
ORDER BY number

스크린 샷

SELECT id,name8000
FROM T
ORDER BY number

스크린 샷


1
따라서 거의 모든 값이 3 자 또는 4 자이고 4자를 초과 할 수없는 경우 "정렬 작업이 tempdb로 유출"되는 것을 방지하려면 VARCHAR (8) 열을 선언하고 CHECK 제약 조건을 사용하여 해당 열을 적용합니다. 너비는 4자를 초과 할 수 없습니다. 어떻게 생각해?
AK

12
@AlexKuznetsov-그 상황에 대해 char(4)어쨌든 변수 열당 2 바이트 오버 헤드가 있으므로 선언합니다 .
Martin Smith

9

모범 사례와는 별도로 (BBlake의 답변)

  • DDL에서 최대 행 크기 (8060) 바이트 및 인덱스 너비 (900 바이트)에 대한 경고가 표시됩니다.
  • 이 한도를 초과하면 DML이 죽습니다.
  • ANSI PADDING ON이 기본값이므로 전체 공백을 저장할 수 있습니다.

38
ANSI PADDING ON에 대해 명확히하기 위해 : nvarcharvarchar유형을 사용할 때 이는 삽입시 후행 공백이 유지됨을 의미하며 char및 에서 와 같이 값이 열 크기에 맞게 공백으로 채워지는 것이 아닙니다 nchar.
Ben M

9

큰 열에는 다소 덜 명확하고 나중에 눈에 띄는 몇 가지 단점이 있습니다.

  • INDEX 에서 사용하는 모든 열 -900 바이트를 초과해서는 안됩니다.
  • ORDER BY 절의 모든 열은 8060 바이트를 초과 할 수 없습니다. 이것은 일부 열에 만 적용되므로 이해하기 약간 어렵습니다. 자세한 내용은 SQL 2008 R2 행 크기 제한 초과 참조)
  • 총 행 크기가 8060 바이트를 초과하면 해당 행에 대해 " 페이지 유출 "이 발생합니다. 이는 성능에 영향을 미칠 수 있습니다 (페이지는 SQLServer의 할당 단위이며 8000 바이트 + 일부 오버 헤드로 고정됩니다.이 값을 초과하는 것은 심각하지 않지만 눈에 띄는 일이므로 쉽게 할 수 있으면 피해야합니다)
  • 다른 많은 내부 데이터 구조, 버퍼 및 최후가 아닌 고유 변수 및 테이블 변수는 모두 이러한 크기를 미러링해야합니다. 크기가 너무 크면 과도한 메모리 할당 이 성능에 영향을 줄 수 있습니다.

일반적으로 열 너비에 대해 보수적이어야합니다. 문제가되는 경우 필요에 맞게 쉽게 확장 할 수 있습니다. 나중에 메모리 문제를 발견하면 나중에 넓은 열을 축소하는 것이 데이터 손실없이 불가능해질 수 있으며 어디서부터 시작해야할지 모를 수 있습니다.

비즈니스 이름의 예에서 표시 할 위치를 생각하십시오. 정말 500자를위한 공간이 있습니까 ?? 그렇지 않은 경우에는 그대로 보관할 필요가 없습니다. http://en.wikipedia.org/wiki/List_of_companies_of_the_United_States 는 일부 회사 이름을 나열하며 최대 길이는 약 50 자입니다. 따라서 최대 열에 100을 사용합니다. 아마 80에 더 가깝습니다.


2

이상적으로는 그보다 더 작은 길이로 줄이고 (500은 적당한 크기가 아님) 데이터가 너무 커져 유용한 오류를 보낼 때 클라이언트 유효성 검사가 포착하는지 확인하는 것이 좋습니다.

varchar가 실제로 사용되지 않은 공간을 위해 데이터베이스에 공간을 예약하지는 않지만 데이터베이스 행이 일부 바이트 수 (정확한 수를 기억하지 않음)보다 넓고 실제로 버려지는 SQL Server 버전을 기억합니다. 적합하지 않은 데이터가 무엇이든. 이러한 바이트 중 특정 수는 SQL Server 내부의 항목을 위해 예약되었습니다.


사실, 이것은 훨씬 더 큰 관심사였습니다. 하지만 요즘에는 공간이 정말 저렴하기 때문에 적어도 내 관점에서는 고려할만한 큰 문제가 아니라고 생각합니다.
BBlake 2010 년

1
@jcollum : 귀하의 예에서 500은 비즈니스 이름에 비해 합리적으로 크기가 조정되지 않은 것 같습니다.
Otis

1
@BBlake : 스토리지 비용에 관계없이 SQL Server에 여전히 행 크기 제약이있는 경우 스토리지의 양은 중요하지 않습니다. 모든 것을 textblob에 저장할 수 있지만 varchar에서 수행 할 수있는 blob에서 수행 할 수없는 SQL 작업이 있습니다.
Otis

2
@Otis : 내 요점은 이것이다 : 비즈니스 이름의 크기에 실제 제약이 없습니다. 어딘가에 법이 없다면. 따라서이 경우에는 해당 필드를 varchar (8000)로 만들고 하루라고 부릅니다. 내 생각은 다음과 같다 : 진짜 제약? varchar (x). 진짜 제약이 없습니까? varchar (8000).
jcollum

24
El Pueblo de Nuestra Señora la Reina de los Ángeles del Río de Porciúncula
StuartLC를보기
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.