VARCHAR vs TEXT
VARCHAR와 TEXT는 MySQL에서 문자열 데이터를 저장할 때 사용하는 주요 데이터 유형이지만, 그들의 용도와 내부적인 동작 방식에는 중요한 차이점이 있습니다. 특히 TEXT는 LOB(대형 객체, Large Object) 유형의 일부로서, 다르게 처리되며 특정 상황에서 비효율적인 동작을 할 수 있습니다.
1. VARCHAR와 TEXT의 개요
- VARCHAR:
- 길이가 가변적인 문자열을 저장하는 데 사용됩니다.
- 최대 길이는 MySQL 5.7에서는 65,535 바이트까지 저장할 수 있으며, 이 최대 길이는 테이블의 행 크기 및 문자 세트에 따라 제한됩니다.
- 데이터는 인라인(inline)으로 테이블의 데이터 페이지에 저장되므로, 빠르게 접근할 수 있습니다.
- VARCHAR는 문자열의 실제 길이에 따라 필요한 만큼의 공간만 사용하여 상대적으로 메모리 및 디스크 공간의 효율적 사용이 가능합니다.
- TEXT:
- 더 큰 크기의 문자열 데이터를 저장할 때 사용됩니다.
- 최대 길이는 64 KB(65,535 바이트)이며, 이는 TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT 등 여러 변종이 존재하는 이유입니다.
- TEXT 유형은 LOB(대형 객체)로 간주되며, 참조 방식으로 데이터를 관리합니다.
- TEXT 데이터는 테이블의 본문 데이터와는 별도로 저장되고, 테이블 행에는 해당 데이터에 대한 포인터만 포함됩니다.
2. VARCHAR와 TEXT의 차이점
- 저장 위치:
- VARCHAR: 테이블의 데이터 페이지에 **인라인(inline)**으로 저장되며, 일반적인 테이블 데이터와 함께 저장됩니다. 이는 데이터 접근 속도를 빠르게 해 줍니다.
- TEXT: 테이블 행과 별도의 영역에 저장됩니다. 데이터는 외부 스토리지에 저장되고, 행에는 **포인터(참조 주소)**만 저장됩니다. 이런 구조 때문에 데이터 접근이 더 복잡하고 상대적으로 느립니다.
- 메모리 사용 및 효율성:
- VARCHAR는 필요에 따라 공간을 효율적으로 사용하며, 데이터가 길지 않으면 실제로 차지하는 메모리 양도 적습니다.
- 반면 TEXT는 데이터를 다른 영역에 저장하고 포인터로 참조하기 때문에, 추가적인 포인터 오버헤드가 발생하고, 인덱스를 만들거나 접근할 때 디스크 I/O가 더 많이 발생하게 됩니다.
- MySQL 서버는 스토리지 엔진과 Handler API를 이용해서 데이터를 주고 받는데, 이때 MySQL 엔진과 InnoDB 스토리지 엔진은 uchar* records[2] 메모리 포인터를 이용해서 레코드 데이터를 주고 받습니다.
- records 메모리 버퍼는 처음 한번 할당되면 많은 커넥션들에 의해서 재사용될 수 있도록 설계되어 있습니다.
- records 메모리 객체는 실제 레코드의 데이터 크기에 관계 없이 최대 크기로 메모리를 할당합니다.
- VARCHAR 타입은 최대 크기가 설정되기 때문에 메모리 공간을 records[2] 버퍼에 미리 할당 받아둘 수 있지만, TEXT나 BLOB와 같은 LOB 컬럼 데이터의 경우 실제 최대 크기만큼 메모리를 할당해 두면 메모리 낭비가 너무 심해지는 문제가 있습니다. 이 때문에 TEXT의 경우 Read/Write 시에 매번 할당을 하게 됩니다.
- 인덱싱:
- VARCHAR 컬럼에 인덱스를 생성하면 인덱스에 전체 문자열이 저장되어 검색 성능을 높일 수 있습니다.
- TEXT 컬럼은 인덱싱 시 문제가 될 수 있습니다. MySQL에서는 TEXT 컬럼의 경우 전체 텍스트 인덱스를 지원하지 않으며, 인덱싱 시 제한이 있습니다. 예를 들어, MySQL에서는 인덱싱 시 처음 255 바이트만 사용할 수 있는 제한이 있습니다.
- 제한 및 사용 사례:
- VARCHAR는 길이가 상대적으로 짧고 명확한 데이터를 저장할 때 적합합니다. 예를 들어 사용자 이름, 이메일 주소, 상태 메시지와 같은 경우입니다.
- TEXT는 대량의 텍스트 데이터, 예를 들어 블로그 포스트 내용, 기사, 댓글 등과 같이 길이가 길고 불규칙한 데이터를 저장하는 데 주로 사용됩니다.
3. TEXT의 비효율성
- 디스크 I/O 증가:
- TEXT 컬럼의 데이터는 별도의 공간에 저장되므로, 해당 데이터를 읽어올 때 추가적인 디스크 I/O가 필요합니다. 이는 쿼리 성능에 부정적인 영향을 미치며, 특히 데이터가 자주 조회되거나 큰 테이블에서 동작할 경우 성능 저하가 심해질 수 있습니다.
- 캐싱 비효율:
- MySQL의 InnoDB와 같은 스토리지 엔진은 데이터를 페이지 단위로 캐시합니다. TEXT 컬럼은 별도의 영역에 저장되기 때문에, VARCHAR처럼 테이블 페이지 내에서 효율적으로 캐싱되지 못하고 더 자주 디스크 접근이 발생하게 되어 버퍼 풀의 효율성이 떨어집니다.
- 메모리 사용과 오버헤드:
- TEXT 유형은 데이터를 가리키는 **포인터(주소)**도 관리해야 하므로, 추가적인 메모리 사용과 오버헤드가 발생합니다. 큰 데이터가 빈번히 삽입되고 삭제되면 메모리 단편화(fragmentation) 문제가 발생할 가능성도 있습니다.
- 인덱스 생성 및 검색 성능:
- TEXT 컬럼은 인덱스 생성에 제한이 있으며, 긴 문자열을 부분적으로 인덱싱하기 때문에 복잡한 검색 조건에서는 비효율적일 수 있습니다. 또한, 모든 문자열을 인덱스에 저장하지 않으므로 LIKE 연산자 등을 사용할 때 검색 성능이 저하될 수 있습니다.
4. VARCHAR vs TEXT 선택 가이드
- VARCHAR 사용:
- 데이터 길이가 예측 가능하고 상대적으로 짧을 때 (1 ~ 65,535 바이트).
- 데이터가 자주 검색되고 인덱스를 통한 빠른 검색이 중요한 경우.
- 예: 사용자 이름, 이메일, 주소 등.
- TEXT 사용:
- 데이터 길이가 매우 길고 가변적이며, 자주 변경되는 큰 텍스트 데이터를 저장할 때.
- 인덱스를 통해 검색하는 것이 중요하지 않고, 주로 전체 텍스트 데이터를 저장하는 경우.
- 예: 블로그 포스트 본문, 긴 설명 필드, 댓글 등.
요약하자면, VARCHAR는 짧고 자주 접근되는 데이터를 효율적으로 처리할 수 있는 반면, TEXT는 큰 텍스트 데이터를 저장하는 데 적합하지만, 내부적으로 별도의 스토리지에 저장되기 때문에 성능상 비효율성이 있습니다. 따라서, 데이터의 크기와 접근 패턴에 따라 두 유형을 적절히 선택하는 것이 중요합니다
'Interview > DB' 카테고리의 다른 글
DB에서 B-Tree, B+ Tree (0) | 2024.10.17 |
---|---|
Database Explain을 통한 최적화 분석 (0) | 2024.10.17 |
MySQL DISTINCT (0) | 2024.10.17 |
MySQL Group by와 Having (0) | 2024.10.17 |
Database Select Query (0) | 2024.10.17 |