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이든 관계없이 같은 시간에 작동합니다.