태그 보관물: innodb

innodb

고정 크기 필드에서 CHAR vs VARCHAR을 사용하면 성능에 어떤 영향을 미칩니 까? 이것은 char이 아닌 varchar로 만들어졌습니다. 데이터베이스를 문자로

MD5 해시를 저장하는 인덱스 열이 있습니다. 따라서 열은 항상 32 자 값을 저장합니다. 어떤 이유로 든 이것은 char이 아닌 varchar로 만들어졌습니다. 데이터베이스를 문자로 변환하기 위해 데이터베이스를 마이그레이션하는 데 어려움이 있습니까? 이것은 InnoDB가 설치된 MySQL 5.0에 있습니다.



답변

비슷한 질문을하기 전에

MySQL VARCHAR 크기의 성능 영향

여기 내 대답의 발췌가 있습니다.

CHAR 대 VARCHAR 사용의 장단점을 인식해야합니다

CHAR 필드를 사용하면 할당하는 것이 정확히 얻는 것입니다. 예를 들어, CHAR (15)는 필드에 문자를 배치하는 방법에 관계없이 15 바이트를 할당하고 저장합니다. 데이터 필드의 크기를 완전히 예측할 수 있으므로 문자열 조작이 간단하고 간단합니다.

VARCHAR 필드를 사용하면 완전히 다른 이야기를 얻을 수 있습니다. 예를 들어 VARCHAR (15)는 실제로는 최대 16 바이트, 데이터의 경우 최대 15 바이트, 데이터의 길이를 저장하기 위해 최소 1 개의 추가 바이트를 동적으로 할당합니다. 저장할 문자열 ‘hello’가 6 바이트가 아닌 경우 5가 아닙니다. 문자열 조작은 항상 모든 형태의 길이 검사를 수행해야합니다.

다음 두 가지 작업을 수행하면 절충이 더 분명해집니다. 1. 수백만 또는 수십억 개의 행 저장 2. CHAR 또는 VARCHAR 인 색인화 열

TRADEOFF # 1 가변 길이 데이터는 더 작은 행을 생성하므로 더 작은 실제 파일을 생성하므로 VARCHAR은 이점을 갖습니다.

TRADEOFF # 2 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)입니다. CHAR(15)IP 주소의 길이는 그다지 다르지 않으며 추가 바이트로 제어되는 문자열 조작의 복잡성이 증가하기 때문에 하트 비트에서 바로 뛰어 넘을 것입니다. 당신은 여전히 ​​그런 PROCEDURE ANALYSE()열에 대해 반대 할 수 있습니다 . VARCHAR을 권장 할 수도 있습니다. 이 경우 내 돈은 여전히 ​​VARCHAR보다 CHAR에 있습니다.

CHAR 대 VARCHAR 문제는 적절한 계획을 통해서만 해결할 수 있습니다. 큰 힘으로 큰 책임이 따릅니다 (진실이지만 사실).

최신 정보

MD5에 관해서 strlen는 전체 행 형식을 전환 할 때 내부 계산을 제거해야합니다. 필드 정의를 변경할 필요가 없습니다.

MD5 키가 유일한 VARCHAR이면, 키 행을 사용하여 테이블 행 형식을 fixed로 변환합니다 . 많은 수의 다른 VARCHAR 필드가있는 경우에도 도움이됩니다. 그 대가로 테이블의 크기가 약 두 배로 확장되었습니다. 그러나 추가 조정 없이도 쿼리 속도가 약 20 % 증가합니다.


답변

로 변환하여 값당 1 바이트 또는 약 3 %를 절약하는 것처럼 보입니다 char. 어쨌든 MD5 를 16 진수 로 저장하면 그만한 가치가 없습니다 binary. 대신에 50 %를 절약 할 수 있습니다.

멀티 바이트 문자 집합을 사용하는 경우 32 바이트 이상을 사용할char(32) 수 있다고 지적한 Ovais (주석 참조)에게 감사합니다 .

unhex16 진수 문자열을 이진수로 변환하는 함수를 사용해야 함을 지적한 Rick James에게 감사합니다 .

create table foo(bar varbinary(100));
insert into foo(bar) values(md5('a'));
insert into foo(bar) values(unhex(md5('a'))); 
select length(bar) from foo;
| 길이 (bar) |
| ---------- : |
| 32 |
| 16 |

db <> 바이올린 여기


답변

내 의견으로는 바꿀 가치가 없습니다. 여기에서 문서를 살펴보면 두 문서의 차이점을 설명해야합니다. 사용 시나리오에서 행 크기와 관련된 추가 오버 헤드에 대해 염려하지 않는 한 실제로 다른 것에 비해 큰 이점을 제공하지 않습니다.

http://dev.mysql.com/doc/refman/5.0/en/char.html

또한 위에 링크 된 문서에 대한 첫 번째 주석을 참고하십시오 … “CHAR은 전체 레코드의 크기가 고정 된 경우에만 액세스 속도를 높입니다. 즉, 가변 크기 개체를 사용하는 경우 모든 개체를 만들 수도 있습니다. VARCHAR도 포함하는 테이블에서 CHAR을 사용하면 속도가 나지 않습니다. “


답변