MySQL-varchar 길이 및 성능


답변:


31

이것은 매우 일반적인 "시험 / 면접 질문"입니다. 나는 최대한 잘 대답 할 것이다.

InnoDB 및 MyISAM (동적 / 컴팩트)의 표준 행 형식에서 a VARCHAR(50)와 a VARCHAR(255)는 문자열 텍스트를 동일한 방식으로 길이와 길이가 1 바이트이고 문자 당 1과 4 바이트 사이의 실제 문자열을 인코딩합니다 (인코딩 및 저장된 실제 문자).

내가 정확히 기억한다면 사실, 나는 누군가가 같은 변경 뭔가 순서에 진수 편집기를 사용하여 데이터 사전을 수정 기억 VARCHAR(50)VARCHAR(100)가 (테이블 재구성을 요구하는, 일반적으로) 동적으로 수행 될 수 있도록. 실제 데이터는 해당 변경의 영향을받지 않았기 때문에 가능했습니다.

VARCHAR(256)길이가 2 바이트 (최소한)가 항상 필요하기 때문에 에서는 그렇지 않습니다.

그래서, 우리는 항상 그 수단을해야한다고 VARCHAR(255)우리는해야하지? 아니요 . 몇 가지 이유가 있습니다.

InnoDB는 varchar를 동적으로 저장할 수 있지만 다른 엔진에는 해당되지 않습니다. MyISAM은 고정 행 크기 형식을 가지며 MEMORY 테이블은 항상 크기가 고정됩니다. 다른 엔진에 관심을 가져야합니까? 예, 직접 사용하지 않더라도 MEMORY 테이블은 중간 결과 (메모리의 임시 테이블)에 매우 일반적으로 사용되며 결과를 미리 알 수 없으므로 테이블을 최대 크기로 만들어야합니다. 가능하다면- VARCHAR(255)그것이 우리 유형이라면. 낭비되는 공간에 대해 생각할 수 있다면 MySQL의 'utf8' charset인코딩을 사용 하는 경우 MEMORY는 길이 당 2 바이트 + 행당 3 * 255 바이트를 예약합니다.(InnoDB에서 몇 바이트 만 걸릴 수있는 값). VARCHAR의 경우에만 백만 테이블에서 거의 1GB입니다. 이로 인해 불필요한 메모리 스트레스가 발생할뿐만 아니라 디스크에서 작업이 수행되어 수천 배가 느려질 수 있습니다. 정의 된 데이터 유형 (콘텐츠와 무관)을 잘못 선택했기 때문에이 모든 것이 가능합니다.

InnoDB에도 영향을 미칩니다. 인덱스 크기는 3072 바이트로 제한되고 단일 열 인덱스는 767 바이트로 제한됩니다 *. 따라서 필드를 완전히 색인화 할 수 없을 가능성이 높습니다VARCHAR(255) (utf8 또는 기타 가변 길이 인코딩을 사용한다고 가정).

또한 InnoDB의 최대 인라인 행 크기는 반 페이지 (약 8000 바이트)이며 BLOB 또는 varchar와 같은 가변 길이 필드는 반 페이지에 맞지 않으면 오프 페이지로 저장할 수 있습니다 . 그것은 무시할 수없는 성능 (때때로 사용에 따라 좋고 나쁘다)에 약간의 영향을 미칩니다. 이로 인해 COMPACT와 DYNAMIC 형식간에 약간의 이상이 발생했습니다. 예를 들어 오류 1118 : 행 크기가 너무 큼을 참조하십시오 . utf8 innodb

마지막으로 @ypercube가 상기 한 것처럼 길이가 바이트를 VARCHAR(255)저장하는 동안 정의가 문자로되어 있기 때문에을 사용하더라도 길이에 1 바이트 이상이 필요할 수 있습니다 . 예를 들어 REPEAT('ñ', 255)utf8에서 2 ^ 255 바이트를 초과하므로 길이를 저장하려면 1 바이트 이상이 필요합니다.

mysql> SELECT LENGTH(REPEAT('ñ', 255));
+---------------------------+
| LENGTH(REPEAT('ñ', 255))  |
+---------------------------+
|                       510 |
+---------------------------+
1 row in set (0.02 sec)

mysql> SELECT CHAR_LENGTH(REPEAT('ñ', 255));
+--------------------------------+
| CHAR_LENGTH(REPEAT('ñ', 255))  |
+--------------------------------+
|                            255 |
+--------------------------------+
1 row in set (0.00 sec)

따라서 일반적인 조언은 가능한 한 가장 작은 유형사용하는 것입니다. 그렇지 않으면 잠재적으로 성능 또는 관리 문제가 발생할 수 있기 때문입니다. 정확한 길이를 모르 더라도 A VARCHAR(100)는 A 보다 낫습니다 . 테이블이 너무 크지 않으면 나중에 정의를 언제든지 변경할 수 있으므로 보수적입니다.VARCHAR(255)VARCHAR(20)

업데이트 : 이모 지 사용과 같이 가변 길이 문자열의 폭발적인 인기로 인해 Oracle은 이러한 경우에 대한 성능 향상을 추진하고 있습니다. 최신 MySQL 버전 (5.6, 5.7)에서 InnoDB는 고유 길이 테이블과 명시 적 임시 테이블 모두에 대한 기본 엔진으로 설정되어 가변 길이 필드가 이제 일류 시민임을 의미합니다. 즉, 문자 길이가 매우 제한된 이유는 적을 수 있지만 여전히 존재합니다.

(*) 두 번째 업데이트 : large_prefix_index는 최신 MySQL 버전 (8.0)에서 기본적으로 활성화되어 있지만 이전 버전이나 여전히 동적 또는 압축 이외의 innodb 파일 / 행 형식을 사용하는 경우에도 마찬가지입니다. 기본적으로 단일 열 인덱스는 최대 3072 바이트입니다.


작은 업데이트 : MySQL-8.0.13 +는 varchars를 효율적으로 저장하는 임시 테이블에 기본적으로 TempTable 을 사용합니다 .
danblack

0

에서 1 바이트와 2 바이트 접두사를 잊어 버리십시오 VARCHARs.

  • 적은 양만큼 성능에 영향을줍니다.
  • 명백한 규칙이 말하는 것보다 더 자주 "2"입니다.

255에 관한 질문이 여러 번 요청되고 답변되었습니다.

  • 너무 길면 VARCHARs오류가 발생할 수 있습니다 CREATE TABLE.
  • 임시 테이블로 전환 할 수 MEMORY와 테이블 VARCHARs로 바뀌 VARCHAR. 예를 들어 VARCHAR(255) CHARACTER SET utf8mb4고정 길이 1020 바이트 를 원한다는 의미 입니다. (이것은 실패 할 것이며 MyISAM을 사용하면 성능이 떨어질 것입니다.)

결론 : 맹목적으로 255 (또는 256)를 사용하지 마십시오. 스키마에 적합한 것을 수행하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.