varchar (max) 어디에서나?


81

모든 SQL Server 2008 문자열 열을 varchar (max)로 만드는 데 문제가 있습니까? 허용되는 문자열 크기는 응용 프로그램에서 관리합니다. 데이터베이스는 내가 제공 한 것만 유지해야합니다. 실제로 들어가는 데이터의 크기에 관계없이 Sql Server 2008에서 모든 문자열 열을 varchar (max) 형식으로 선언하면 성능이 저하됩니까?


1
내 독서에서는 Sql Server varchar 열 자체가 '자동 크기 조정'처럼 들립니다. 주어진 값의 최대 길이가 20 인 varchar (max) 열이 varchar (20) 열과 같지 않습니까?
BowserKingKoopa

답변:


49

를 사용 VARCHAR(MAX)하면 기본적으로 SQL Server에 "가장 잘 보이는 방법으로 값을이 필드에 저장"하는 것이므로 SQL Server는 값을 일반 VARCHAR또는 LOB (대형 개체) 로 저장할지 여부를 선택합니다 . 일반적으로 저장된 값이 8,000 바이트 미만이면 SQL Server는 값을 일반 VARCHAR유형 으로 처리합니다 .

저장된 값은 컬럼들이 다른 LOB 유형과 똑같이, LOB 페이지에있는 페이지를 유출 할 수 (너무 큰 경우 text, ntextimage) -이 추가적인 페이지에 저장된 데이터를 읽기 위해 필요한 읽기 발생하는 경우 그러나 이것은 저장된 값이 너무 큰 경우에만 발생합니다 .

실제로 SQL Server 2008 이상에서는 데이터가 고정 길이 데이터 형식 (예 :)을 사용하더라도 추가 페이지로 오버플로 될 수 VARCHAR(3,000)있지만 이러한 페이지를 행 오버플로 데이터 페이지라고하며 약간 다르게 처리됩니다.

짧은 버전 : 사용의 어떤 단점이없는 스토리지 관점에서 VARCHAR(MAX)이상 VARCHAR(N)일부가 N.

(이는 다른 가변 길이 필드 유형 NVARCHARVARBINARY) 에도 적용됩니다.

참고로- 열에 인덱스를 만들 수 없습니다.VARCHAR(MAX)


이것은 nullable 필드에만 해당 될 수 있습니다. Null이 아닌 각 varchar (max) 또는 nvarchar (max) 열에는 24 바이트의 추가 고정 할당이 필요합니다. docs.microsoft.com/en-us/sql/t-sql/data-types/…
Liazy

34

인덱스의 너비는 900 바이트를 초과 할 수 없습니다. 따라서 인덱스를 만들 수 없습니다. 데이터가 900 바이트 미만이면 varchar (900)을 사용합니다.

이것은 한 가지 단점입니다.

  • 정말 나쁜 검색 성능
  • 고유 한 제약 없음

그러나 varchar (max) 열에 900 바이트보다 큰 값이 없으면 어떻게 될까요? 그러면 색인이 생성됩니까? 내가 읽고있는 많은 내용이 varchar 열 유형이 데이터가 입력 될 때 최대 크기까지 자동 크기 조정되는 것처럼 들리기 때문에 혼란 스럽습니다. 이것은 데이터베이스가 아니라 최대 값을 결정해야하는 애플리케이션이기 때문에 내가 원하는 것에 완벽 할 것입니다.
BowserKingKoopa 2010 년

3
인덱스를 만들 때 경고가 표시되고> 900을 삽입하려고하면 오류가 발생합니다.하지만 데이터가 항상 900 미만이면 900을 사용하지 않는 이유는 무엇입니까? 예, 그들은 가변 길이 문자열로 저장됩니다.
gbn

8
내 데이터가 항상 900 미만인지는 모르겠습니다. 비즈니스 로직 문제입니다. 해당 규칙이 변경되면 비즈니스 로직에서 변경해야합니다. 데이터베이스도 변경할 필요가 없습니다. 어쨌든 그게 내 목표입니다. 눈에 띄는 성능 저하없이 데이터베이스에서 문자열 크기에 대한 우려를 제거 할 수 있는지 확인합니다.
BowserKingKoopa 2010 년

2
긴 텍스트 열을 인덱싱하는 것이 얼마나 자주 유용합니까? varchar (200) 열과 같은 것을 인덱싱 할 가치가 있습니까? 결국 인덱스 자체는 비효율적입니다. 긴 "정확한 일치"를 검색 할 필요가 없을 것 같습니다. 그리고 패턴 검색은 패턴의 시작이 알려진 경우에만 도움이됩니다.
환멸

9

Simon Sabin은 얼마 전에 이것에 대한 게시물을 썼습니다. 지금 당장 잡을 시간이 없지만 기본적으로 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)의. 일반적인 원칙은 조심하는 것입니다. 최대 값이 필요하지 않은 경우 최대 값을 사용하지 마십시오. 8000 자 이상이 필요한 경우 확실합니다.




첫번째. OMG Ponies 제작.
Rob Farley

실제 링크를 찾을 시간이 없어서 미안합니다. 대답을 풀고 싶을 때 회의에 들어 가려고했습니다.
Rob Farley


6

이 질문에 대해 특별히 언급하지 않은 몇 가지 사항이 있습니다.

  1. 2005/2008/2008 R2에서 LOB 열이 인덱스에 포함되어 있으면 온라인 인덱스 재 구축이 차단됩니다.
  2. 2012 년에는 온라인 인덱스 다시 작성 제한이 해제되었지만 LOB 열은 온라인 작업으로 NOT NULL 열 추가 새 기능에 참여할 수 없습니다 .
  3. 이 데이터 유형의 열을 포함하는 행에서 잠금을 더 오래 사용할 수 있습니다. ( )

varchar(8000)모든 곳 에서가 아닌지에 대한 내 대답에는 몇 가지 다른 이유가 포함되어 있습니다 .

  1. 쿼리는 데이터 크기로 정당화되지 않는 엄청난 메모리 부여를 요청하게 될 수 있습니다.
  2. 트리거가있는 테이블에서 버전 관리 태그가 추가되지 않은 최적화를 방지 할 수 있습니다.

5

앞서 비슷한 질문을했습니다. 흥미로운 답변을 받았습니다. 여기에서 확인 하세요 한 사람이 넓은 열을 사용하는 것의 단점에 대해 이야기하는 사이트가 있었지만 응용 프로그램에서 데이터가 제한되어 있으면 내 테스트에서 반증했습니다. 열에 인덱스를 만들 수 없다는 사실은 항상 인덱스를 사용하지 않을 것임을 의미합니다 (개인적으로는 그다지 많이 사용하지는 않지만 그 점에서 약간 순수 주의자입니다). 그러나 저장되어 있지 않다는 것을 알고 있다면 그렇게 나쁘다고 생각하지 않습니다. varchar (max)가 포함 된 레코드 집합 (또는 char 또는 varchar 인 넓은 열)에서 열에 대해 정렬을 수행하면 성능이 저하 될 수 있습니다. 인덱스로 해결할 수 있지만 (필요한 경우) varchar (max)에 인덱스를 넣을 수는 없습니다. 미래에 당신의 칼럼을 증명하고 싶다면, 왜 그것들을 합리적인 것에 두지 않는 것이 좋습니다. 예를 들어 이름 열은 최대 대신 255 자입니다.


2

모든 열에서 varchar (max)를 사용하지 않는 또 다른 이유가 있습니다. 같은 이유로 (잘못된 소프트웨어 또는 사용자 항목으로 인한 정크로 테이블을 채우는 것을 방지하기 위해) 검사 제약 조건을 사용하여 의도 한 것보다 훨씬 많은 데이터를 추가하는 잘못된 프로세스로부터 보호하고 싶습니다. 예를 들어, 누군가 또는 무언가가 City 필드에 3,000 바이트를 추가하려고 시도하면 무언가 잘못되었다는 것을 확실히 알 수 있으며 가능한 한 빨리 디버그하기 위해 프로세스가 중단되는 것을 중지하고 싶을 것입니다. 또한 3000 바이트 도시 이름은 유효하지 않을 수 있으며 사용하려고하면 보고서 등을 엉망으로 만들 수 있음을 알 수 있습니다.


1

이상적으로는 필요한 것만 허용해야합니다. 특정 열 (예 : 사용자 이름 열)의 길이가 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 바이트에 가까워 질 것입니까?


3
나는 이것을 "할당"이라고 특성화하는 것이 정확하지 않다고 생각합니다. DB는 실제로 어디에서나 2 ^ 31-1 바이트를 예약하지 않습니다.
Scott Stafford

1
"사용자 이름 열 [..]의 길이는 20자를 넘지 않습니다."-고객이 어느 날 더 길어야한다고 결정할 때까지는 좋습니다. 우리 모두 거기에있었습니다. :)
스티브 스미스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.