VARCHAR(MAX) 와 NVARCHAR(MAX) 의 단점
VARCHAR 와 NVARCHAR 는 유니코드 라는 점에서 다르기 때문에 VARCHAR 로 설명하겠습니다.
VARCHAR(N) 컬럼에 데이터를 저장할 때에는 물리적으로 같은 방식으로 저장됩니다.
이 말은, 어떤 특정한 동작없이 블록에 바로 쓰인다는 말을 뜻합니다.
그러나 VARCHAR(MAX) 컬럼에 저장하는 경우에는 TEXT 타입처럼 다뤄지게 됩니다.
이는 저장을 위한 추가적인 절차가 필요하다는 뜻입니다. ( 단, 저장되는 데이터길이가 8000 자 이상인 경우 )
왜 8000 자 이상인가? 8K 블록에는 최대 8000 자를 저장할 수 있으며, 이를 넘어가게 되는 경우 오버플로우가 발생하게 됩니다.
out of row 라고 말하며, 이를 저장하기 위해서는 포인터가 사용되게 됩니다.
어느 다른 공간에 해당 데이터를 저장하고 난 후 이 저장된 공간을 가르키는 포인터를 SQL Server 는 저장하게 된다는 말입니다.
SQL Server 는 먼저 in row 방식으로 데이터를 저장하려고 시도한 후에 8K 를 초과하게 되면 out of row 방식으로 저장하게 됩니다.
in row: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms189087(v=sql.105)
out of row ( 8KB 초과 ): https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms186981(v=sql.105)
또한 해당 컬럼에는 인덱스를 생성할 수 없습니다.
물론 큰 N 값을 가지는 VARCHAR(N) 컬럼에 인덱스를 생성하는것도 보통일은 아니지만요.
만약 해당 타입에 8000K 보다 작은 데이터만 들어오고, 인덱스를 생성할 계획이 없다면
이 컬럼은 일반 VARCHAR(N) 과 같은 방식으로 동작하게 될 것입니다.
그러나 후에 있을 관리자를 위해서는 알맞은 컬럼을 쓰는게 좋습니다. :)
( 관리자가 왜 VARCHAR(MAX) 인데 이렇게 짧은 데이터만 넣었지? 라는 질문을 안가지도록요. )
VARCHAR(N) VS VARCHAR(MAX) 성능 테스트
SET NOCOUNT ON;
--===== VARCHAR(10) 타입으로 100만건을 출력하는 테스트
DECLARE @SomeString VARCHAR(10),
@StartTime DATETIME;
--=====
SELECT @startTime = GETDATE();
SELECT TOP 1000000
@SomeString = 'ABC'
FROM master.sys.all_columns ac1,
master.sys.all_columns ac2;
SELECT testSize='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== VARCHAR(4000) 타입으로 100만건을 출력하는 테스트
DECLARE @SomeString VARCHAR(4000),
@StartTime DATETIME;
SELECT @startTime = GETDATE();
SELECT TOP 1000000
@SomeString = 'ABC'
FROM master.sys.all_columns ac1,
master.sys.all_columns ac2;
SELECT testSize='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== VARCHAR(MAX) 타입으로 100만건을 출력하는 테스트
DECLARE @SomeString VARCHAR(MAX),
@StartTime DATETIME;
SELECT @startTime = GETDATE();
SELECT TOP 1000000
@SomeString = 'ABC'
FROM master.sys.all_columns ac1,
master.sys.all_columns ac2;
SELECT testSize='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
위 쿼리는 VARCHAR(10), VARCHAR(4000), VARCHAR(MAX) 를 100만건씩 루프하는 쿼리입니다.
VARCHAR(MAX) 는 포인터를 사용하기 때문에 더 느린것을 알 수 있습니다.
VARCHAR(N) VS VARCHAR(MAX) UI 테스트
사진으로 보겠습니다.
어느 테이블이 이후 관리자가 인수인계 받았을 때 관리하기 좋을까요?
이 외의 VARCHAR(MAX) 의 단점
1. 과연 모든 데이터베이스들이 MAX 라는 옵션을 지원할까요?
2. 특정 문자열이 넘어가는 경우를 제어하고 싶은데 MAX 로는 제어가 가능할까요?
3. 성능상의 문제도 발생하겠죠.
4. 플랜은 제대로 풀릴 수 있을까요?
이상입니다.
'SQL Server > SQL Server 기타' 카테고리의 다른 글
[MSSQL] syspolicy_purge_history 는 무엇일까? (0) | 2019.12.11 |
---|---|
[MSSQL] VLF 개수에 따른 성능 차이 (0) | 2019.08.06 |
[MSSQL] WITH(NOLOCK) 과 잠금 모드에 대해 (0) | 2019.06.17 |
[MSSQL] Batch Requests/sec 와 Transactions/sec 의 차이점 (1) | 2019.06.03 |
[MSSQL] CheckPoint (검사점) 주기 설정하기 (0) | 2019.06.03 |