varchar 크기간에 MySQL의 성능 차이가 있습니까? 예를 들어, varchar(25)
와 varchar(64000)
. 그렇지 않은 경우 공간이 부족하지 않도록 최대 크기의 모든 varchar를 선언하지 않는 이유가 있습니까?
varchar 크기간에 MySQL의 성능 차이가 있습니까? 예를 들어, varchar(25)
와 varchar(64000)
. 그렇지 않은 경우 공간이 부족하지 않도록 최대 크기의 모든 varchar를 선언하지 않는 이유가 있습니까?
답변:
CHAR 대 VARCHAR 사용의 장단점을 인식해야합니다
CHAR 필드를 사용하면 할당하는 것이 정확히 얻는 것입니다. 예를 들어, CHAR (15)는 필드에 문자를 배치하는 방법에 관계없이 15 바이트를 할당하고 저장합니다. 데이터 필드의 크기를 완전히 예측할 수 있으므로 문자열 조작이 간단하고 간단합니다.
VARCHAR 필드를 사용하면 완전히 다른 이야기를 얻을 수 있습니다. 예를 들어, VARCHAR (15)는 실제로는 최대 16 바이트, 데이터의 경우 최대 15 바이트, 데이터의 길이를 저장하기 위해 최소 1 개의 추가 바이트를 동적으로 할당합니다. 저장할 문자열 'hello'가 6 바이트가 아닌 경우 5가 아닙니다. 문자열 조작은 항상 모든 형태의 길이 검사를 수행해야합니다.
두 가지 작업을 수행 할 때 절충이보다 분명해집니다.
1. 수백만 또는 수십억 개의 행 저장
2. CHAR 또는 VARCHAR 인 색인화 열
가변 길이 데이터가 더 작은 행을 생성하여 더 작은 실제 파일을 생성하므로 VARCHAR은 이점을 가지고 있습니다.
CHAR 필드는 고정 필드 너비로 인해 문자열 조작이 덜 필요하므로 CHAR 필드에 대한 인덱스 조회는 VARCHAR 필드보다 평균 20 % 빠릅니다. 이것은 내 추측에 해당되지 않습니다. MySQL Database Design and Tuning 책 은 이것을 증명하기 위해 MyISAM 테이블에서 놀라운 것을 수행했습니다. 이 책의 예제는 다음과 같은 작업을 수행했습니다.
ALTER TABLE tblname ROW_FORMAT=FIXED;
이 지시문은 VARCHAR이 CHAR로 작동하도록합니다. 나는 2007 년 이전 직장에서이 작업을 수행했으며 300GB 테이블을 가져 와서 다른 것을 변경하지 않고 인덱스 조회를 20 % 늘 렸습니다. 출판 된대로 작동했습니다. 그러나 거의 두 배 크기의 테이블을 만들었지 만 단순히 트레이드 오프 # 1로 돌아갑니다.
저장된 데이터를 분석하여 MySQL이 열 정의에 권장하는 것을 확인할 수 있습니다. 테이블에 대해 다음을 실행하십시오.
SELECT * FROM tblname PROCEDURE ANALYSE();
그러면 전체 테이블을 순회하며 포함 된 데이터, 최소 필드 값, 최대 필드 값 등을 기준으로 모든 열에 대한 열 정의를 권장합니다. 때로는 CHAR 대 VARCHAR을 계획 할 때 상식을 사용해야합니다. 다음은 좋은 예입니다.
IP 주소를 저장하는 경우 해당 열의 마스크는 최대 15 자 (xxx.xxx.xxx.xxx)입니다. IP 주소의 길이가 그다지 다르지 않으며 추가 바이트로 제어되는 문자열 조작의 복잡성이 증가하기 때문에 CHAR (15)에서 하트 비트로 바로 뛰어 올 것입니다. 이러한 열에 대해 여전히 PROCEDURE ANALYSE ()를 수행 할 수 있습니다. VARCHAR을 권장 할 수도 있습니다. 이 경우 내 돈은 여전히 VARCHAR보다 CHAR에 있습니다.
CHAR 대 VARCHAR 문제는 적절한 계획을 통해서만 해결할 수 있습니다. 큰 힘으로 큰 책임이 따릅니다 (진실이지만 진실)
이에 대한 대답은 실제로 다소 복잡합니다. 짧은 버전 : 차이가 있습니다.
결과 (예 : GROUP BY
명령문) 를 필터링하기 위해 임시 테이블을 작성할 때 전체 길이가 할당됩니다.
유선 프로토콜 (행을 클라이언트에 전송)은 더 큰 길이를 할당 할 것입니다.
스토리지 엔진이 적절한 varchar를 구현하지 않을 수도 있습니다.
(2) 나는 유선 프로토콜이 친숙한 것이 아니라는 것을 인정하지만, 일반적인 조언은 길이를 추측하기 위해 최소한의 노력을 기울이는 것입니다.
이 스레드의 대부분의 답변은 5 세이며 InnoDB와 utf8이 기본값이되기 전에 작성되었습니다. 다시 시작하겠습니다 ...
쿼리에 내부 임시 테이블이 필요한 경우 테이블을 사용하려고 MEMORY
합니다. 그러나 MEMORY는
TEXT
/ BLOB
열을 가져올 수 없습니다 TINYTEXT
.VARCHAR
현재 버전에서는 512보다 약간 더 큽니다.또한, 그주의 VARCHARs
로 전환된다 CHARs
. 따라서 열의 내용에 관계없이 765 바이트 VARCHAR(255)
로 CHARACTER SET utf8
확장됩니다. 그런 다음 트리거 될 수 있습니다.
MEMORY
테이블 중 하나를보다 더 얻는다 max_heap_table_size
거나 tmp_table_size
, 그것은의 MyISAM로 변환하고 잠재적으로 디스크에 유출됩니다.따라서 VARCHAR(25)
더 머무를 가능성이 높 MEMORY
으므로 더 빠릅니다. (255)
좋은으로하지 않고, (64000)
나쁘다.
(미래에 임시 테이블은 아마도 InnoDB
이며이 답변의 일부를 수정해야 할 것입니다.)
크기가 큰 varchar 열은 전체 테이블에 대한 쿼리가 임시 테이블을 사용하기 쉽습니다. 고성능 MySQL 책에 따르면. 옵티마이 저가 메모리에서이 쿼리를 실행할 수 있는지 확인하거나 임시 테이블이 필요한 경우 테이블 정의를 기반으로 행 크기를 확인합니다. 즉, 속도로 인해 64K 문자를 얼마나 많이 보려고하지는 않습니다. 실제로 사용하고 있습니다. 그렇기 때문에 작가는 열에 들어가는 실제 가능한 값을 넘어서 그 정의 방식을 확장하지 말 것을 권장합니다. 실제로 실제 데이터 크기가 RAM에 적합하더라도 임시 테이블에 대한 추가 쿼리에 대해 스스로를 설정 한 경우 이제 피할 수있는 I / O 페널티가 발생했습니다.
더 작은 필드는 인덱스에서 직접 포함 할 수 없지만 더 긴 필드는 직접 계산할 수 없다는 것을 이해합니다. 이러한 제한으로 인해 문자열을 인덱싱 가능하게하려면 더 짧게 유지해야합니다. 그렇지 않으면 아니요, 두 varchar의 정렬 방식이므로 정렬 또는 비교와 같은 ops는 필드가 25이든 MAX이든 관계없이 같은 시간에 작동합니다.