MySQL 테이블에서 varchar 길이의 중요성


112

행이 동적으로 삽입되는 MySQL 테이블이 있습니다. 문자열의 길이를 확신 할 수없고 잘리는 것을 원하지 않기 때문에 일반적으로 필요한 것보다 훨씬 큰 varchar (200)을 만듭니다. varchar 필드에 필요한 것보다 훨씬 더 많은 길이를 제공하는 데 큰 성능 저하가 있습니까?


VARCHAR(255) utf8mb411.5MB로 측정 된 150k 행 이있는 단일 인덱싱 된 열이 있는 테이블 . VARCHAR(48) utf8mb4동일한 데이터 (최대 길이 46 자) 가있는 인덱스 열이있는 테이블이 4.5MB를 사용했습니다. 쿼리에서 실제로 큰 차이는 아니지만 색인이 생성됩니다. 그러나 쿼리 I / O 및 데이터베이스 백업과 같은 것들을 추가합니다.
Code4R7

답변:


59

아니요, 해당 열에 저장하는 값이 항상 (예를 들어) 50 자 미만이면 열을 다음과 같이 선언 varchar(50)하거나 varchar(200)동일한 성능을 갖는다는 의미입니다.


9
정확히 사실이 아닙니다. 의 대답을 참조하십시오 빌 Karwin
hejdav

5
같은 답변은 문서, 벤치 마크 또는 이와 유사한 것으로 뒷받침되어야한다고 생각합니다.
Gokhan Sari

301

성능에 미치는 한 가지 영향이 있습니다. MySQL에서는 임시 테이블과 MEMORY테이블이 VARCHAR열을 고정 길이 열로 저장 하고 최대 길이까지 채 웁니다. VARCHAR필요한 가장 큰 크기보다 훨씬 더 큰 열 을 디자인 하면 필요한 것보다 더 많은 메모리를 소비하게됩니다. 이는 캐시 효율성, 정렬 속도 등에 영향을 미칩니다.


33
+1. 행을 검색하기 위해 버퍼를 설정할 때 최대 크기에 충분한 공간을 할당하는 JDBC 드라이버도 있습니다. 말할 필요도없이,이 많은 불안을 야기하고 일부 광대 그냥 완료 VARCHAR (50000)가있을 때 단지의 경우 누군가에이를 갊이 있으리라 정말 큰 성 :-)이
paxdiablo

21
+1. 이것은 중요한 영향이며 이것이이 질문의 진정한 답이라고 믿습니다.
Emre Yazici

6
이 답변과 수락 된 답변은 모두 OP에 대한 정답을 이해하는 데 필요합니다.
kd8azz

2
실제로 이러한 MEMORY테이블이 너무 큰 것으로 간주되면 디스크에 기록되어 성능이 크게 저하됩니다.
Timo

1
이 대답은 어떤 스토리지 엔진에 해당하는지 지정하는 것과 관련이 있습니다 ( dev.mysql.com/doc/refman/8.0/en/… 은 임시 테이블이 항상 MySQL 8부터 InnoDB임을 나타냅니다. 변경 사항이 있습니까?) 및 주장을 뒷받침하는 문서에 대한 링크가 있습니다. Stack Exchange에서 귀하의 결과물을 본 것을 보면이 글을 썼을 때 귀하가 옳았다는 믿음이 있지만 상황이 변경되었을 수 있으며 링크는 모두 다른 사람에게 좋은 본보기가되고 나머지 사람들이 찾을 수 있도록 가르치는 데 도움이 될 것입니다. 우리 자신을위한 이런 종류의 정보.
Mark Amery 2011

14

VARCHAR은 "가변 문자"를 나타 내기 때문에 설명하는 상황에 이상적입니다. 예에 따라 제한은 200 자이지만 그보다 적은 것은 허용 되며 할당 된 열 크기를 채우지 않습니다.

VARCHAR은 또한 공간을 덜 차지합니다. 값은 1 바이트 또는 2 바이트 길이 접두사와 데이터로 저장됩니다. 길이 접두사는 값의 바이트 수를 나타냅니다. 값이 255 바이트 이하를 요구하는 경우 열은 1 개의 길이 바이트를 사용하고, 값이 255 바이트 이상을 요구할 수있는 경우 2 개의 길이 바이트를 사용합니다.

MySQL CHAR와 VARCHAR 데이터 유형을 비교하는 자세한 정보는 이 링크를 참조하십시오 .


1
MySQL 스토리지 (CHAR 및 VARCHAR에 대한)에 관심이있는 모든 사람은이 답변에 언급 된 링크를 읽어야합니다. 감사!
Pascal

14

크기는 성능입니다! 크기가 작을수록 좋습니다. 오늘이나 내일은 아니지만 언젠가는 어떤 디자인을 설계하든 심각한 병목 현상이 발생할 때 테이블이 커질 것입니다. 그러나 먼저 발생할 가능성이있는 설계 단계에서 잠재적 인 병목 현상 중 일부를 예측하고 계획을 재고하거나 서버를 추가하여 수평으로 확장해야 할 때까지 DB가 빠르고 행복하게 수행되는 시간을 늘릴 수 있습니다.

귀하의 경우에는 많은 성능 누수가 발생할 수 있습니다. 큰 조인은 거의 불가능합니다. varchar 있습니다. 열 합니다. 이러한 열에 대한 인덱싱은 진정한 킬러입니다. 디스크는 데이터를 저장해야합니다. 하나의 메모리 페이지는 더 적은 행을 보유 할 수 있으며 테이블 스캔은 훨씬 느립니다. 또한 쿼리 캐시는 여기서 도움이되지 않을 것입니다.

스스로에게 물어보아야합니다. 연간 몇 번의 삽입물이 발생할 수 있습니까? 평균 길이는 얼마입니까? 실제로 200 자 이상이 필요합니까? 아니면 사용자에게 최대 길이를 알려주는 경우에도 애플리케이션 프런트 엔드에서이를 포착 할 수 있습니까? 빠른 인덱싱 및 스캔을 위해 테이블을 좁은 테이블로 분할하고 확장 크기의 덜 자주 필요한 추가 데이터를 보관하기 위해 다른 테이블로 분할 할 수 있습니까? 가능한 varchar 데이터를 범주에 입력하여 데이터 중 일부를 int 또는 bool 유형의 작은 열로 추출하고 그런 식으로 varchar 열을 좁힐 수 있습니까?

여기서 많은 일을 할 수 있습니다. 첫 번째 가정을 한 다음 실제 측정 된 성능 데이터를 사용하여 단계별로 다시 설계하는 것이 가장 좋습니다. 행운을 빕니다.


디자인 옵션을 나열하고 영향력을 탐색하려면 +1. 내 질문에도 매우 유용합니다. stackoverflow.com/q/12083089/181638
Assad Ebrahim

5
최대 길이를 높게 설정하면 실제 성능에 영향이 있습니까? 아니면 실제 크기에 따라 성능이 결정됩니까?
poolie 2013-06-14

5

공연? 아니요. 디스크 스토리지? 예,하지만 저렴하고 풍부합니다. 데이터베이스가 테라 바이트 규모로 성장하지 않는 한 괜찮습니다.


이 답변이 게시 된 지 6 년 만에 반대 투표가되었고 다른 답변은 없었습니다. 보복적이고 사소한 것 같습니다. 이 답변에는 잘못된 것이 없습니다. 중재자?
duffymo

1
말했듯이 성능에 영향을 미칩니다. 또한 디스크 스토리지도 무료가 아닙니다. 더 넓은 열은 더 많은 디스크 읽기 / 쓰기를 의미하고 (디스크 액세스가 느리게 진행됨) 인덱스도 더 넓어 유용성이 떨어집니다. 두 가지 모두 성능에 부정적인 영향을 미칩니다. 소규모 데이터베이스에서는 무시할 수 있을지 모르지만 기가 바이트 / 테라 바이트 규모에서는 확실히 중요합니다. 100 레지스터 테이블의 경우 중요하지 않습니다.
Alejandro

5

여러분 중 일부는 .NET varchar(200)보다 디스크에서 더 많은 테이블 크기를 차지 한다고 잘못 생각 하고 varchar(20)있습니다. 그렇지 않다. 255자를 넘을 때만 mysql은 varchar필드 데이터 의 길이를 결정하기 위해 추가 바이트를 사용합니다 .


9
임시 테이블과 MEMORY테이블 에는 그렇지 않습니다 .
궤도의 경쾌함 레이스

4
선택 쿼리가 임시 테이블 (작업 별 그룹 및 순서)을 사용할 때마다 varchar (200)을 char (200)로 변환하고 성능이 저하됩니다.
Jamie

1

성능 저하가있을 수 있지만 일반적으로 대부분의 사용자가 알아 차릴 수있는 수준은 아닙니다.

각 필드의 크기를 미리 알면 MySQL은 각 필드 / 행 사이에 얼마나 많은 바이트가 있는지 정확히 알고 모든 데이터를 읽지 않고 페이지 앞으로 이동할 수 있습니다. 가변 문자를 사용하면 이러한 최적화 기능이 저하됩니다.

varchar가 데이터 조각화로 인해 성능 저하를 초래합니까?

더 나은 것은 char 대 varchar 입니다.

대부분의 경우 어느 쪽이든 괜찮지 만 차이 있으며 대규모 데이터베이스의 경우 둘 중 하나를 선택해야하는 이유가 있습니다.


0

char가 아닌 varchar이기 때문에 크기는 실제 길이와 문자열 자체를 나타내는 내부 필드를 기반으로합니다. 따라서 varchar (200)을 사용하는 것은 더 많이 저장할 수 있다는 점을 제외하고는 varchar (150)을 사용하는 것과 크게 다르지 않습니다.

그리고 행이 커지면 업데이트에서 어떤 일이 발생하는지 고려해야합니다. 그러나 이것이 드물다면 괜찮을 것입니다.


0

데이터 유형 이름에 따라 이것이 VARCHAR, 즉 가변 문자 데이터 저장소임을 시사하므로 mysql 엔진 자체는 저장된 데이터에 따라 사용되는 메모리를 할당하므로 내 지식에 따라 성능 저하가 없습니다.


0

대부분의 시나리오에서 char 열과 동일하게 varchar 열을보고 길이를 보수적으로 설정해야합니다. 최대 길이에 대한 의사 결정에 영향을 미치는 것으로 항상 var 수정자를 생각할 필요는 없습니다. 제공된 문자열의 길이가 다양하다는 것은 성능 힌트로보아야합니다.

데이터베이스 내부에 엄격하게 따라야하는 지시문이 아니며 완전히 무시할 수 있습니다. 그러나 때로는 구현이 이상적인 세계에 있어서는 안되는 경우에도 누출 (예 : 고정 길이 및 패딩)이 발생할 수 있으므로주의해야합니다.

varchar (255)가 있으면 모든 상황에서 항상 char (255)와 다르게 동작 할 것이라는 성능을 보장 할 수 없습니다.

저장소 요구 사항에 대한 설명서에 제공된 조언에 따라 255, 65535 등과 같은 항목으로 설정하는 것이 쉬워 보일 수 있습니다. 이것은 0 (예, 그것은 일입니다)과 255 사이의 모든 값이 동일한 영향을 미칠 것이라는 인상을줍니다. 그러나 그것은 완전히 보장 될 수있는 것이 아닙니다.

스토리지 요구 사항은 행 스토리지 측면에서 적절하고 성숙한 영구 스토리지 엔진에 대한 사실이거나 좋은 지표 인 경향이 있습니다. 인덱스와 같은 것에 대한 강력한 지표는 아닙니다.

때로는 어려운 질문입니다. 문자열의 한 조각이 얼마나 긴 시간 내에 있어야한다는 것을 알고있는 가장 높은 경계까지 설정해야하지만 영향은 없습니다. 불행히도 이것은 종종 사용자가 해결해야 할 일이며 실제로는 다소 임의적입니다. 정확히 확실하지 않은 경우가있을 수 있기 때문에 문자열을 너무 크게하지 않는다고 말할 수는 없습니다.

문자열이 잘리지 않고 너무 길면 MySQL 쿼리에서 오류가 발생하도록해야 최소한 오류 발생으로 인해 너무 짧을 수 있는지 알 수 있습니다. 열을 확대하거나 축소하기 위해 열의 크기를 조정하는 것은 비용이 많이 드는 DDL 작업 일 수 있으므로 염두에 두어야합니다.

길이와 성능이 중요한 곳에서도 캐릭터 세트를 고려해야합니다. 길이는 바이트가 아닌 이것을 참조합니다. 예를 들어 utf8을 사용하는 경우 (MB4가 아님) varchar (255)는 실제로 varbinary (3 * 255)입니다. 테스트를 실행하지 않고 소스 코드 / 문서를 자세히 살펴 보지 않고도 이런 일이 실제로 어떻게 진행되는지 알기 어렵습니다. 이로 인해 과도한 길이가 예기치 않게 부풀려진 영향을 미칠 수있는 범위가 있습니다. 이것은 성능에만 적용되는 것이 아닙니다. 언젠가 varchar 열의 문자 집합을 더 큰 것으로 변경해야하는 경우 피할 수있는 긴 문자열이 존재하도록 허용하면 아무런 의존없이 일부 제한에 도달 할 수 있습니다. 이것은 일반적으로 상당히 틈새 문제이지만 발생합니다.

MAX (LENGTH (column))이 항상 64 미만인 것으로 판명되면 (예 : 열 정의와 일치하지 않는 입력에 제한이 있다고 결정된 경우) varchar (255)가있는 경우 일부 시나리오에서 필요한 것보다 4 배 더 많은 공간을 사용하게 될 가능성이 높습니다.

여기에는 다음이 포함될 수 있습니다.

  • 다른 엔진, 일부는 모두 무시할 수 있습니다.
  • 예를 들어 업데이트 또는 삽입과 같은 버퍼 크기는 전체 255를 할당해야 할 수 있습니다 (이를 증명하기 위해 소스 코드를 확인하지는 않았지만 가상 일뿐입니다).
  • 인덱스, 많은 varchar (255) 열에서 복합 키를 만들려고하면 즉시 분명해질 것입니다.
  • 중간 테이블 및 가능한 결과 집합. 트랜잭션이 작동하는 방식을 고려할 때 정의 된 제한과는 반대로 열에서 실제 최대 문자열 길이를 사용하는 것이 항상 가능한 것은 아닙니다.
  • 내부 예측 최적화는 최대 길이를 입력으로 사용할 수 있습니다.
  • 데이터베이스 구현 버전 변경.

경험상 varchar가 어쨌든 필요한 것보다 더 길어야 할 필요는 없습니다. 성능 문제가 있든 없든 가능할 때 그것을 고수하는 것이 좋습니다. 데이터 크기를 샘플링하거나, 실제 한계를 적용하거나, 질문 / 연구를 통해 실제 한계를 알아 내기 위해 더 많은 노력을 기울이는 것이 이상적인 접근 방식입니다.

할 수 없을 때, 의심스러운 경우에 대해 varchar (255)와 같은 작업을 수행하려면 과학을 수행하는 것이 좋습니다. 이것은 테이블을 복제하고, var char 열의 크기를 줄인 다음 원본에서 데이터를 복사하고 인덱스 / 행 데이터의 크기를 확인하는 것으로 구성 될 수 있습니다 (열도 인덱싱하고 기본 키로 시도해보십시오). 행이 기본 키로 정렬되므로 InnoDB에서 다르게 동작 할 수 있습니다.) 최소한 이렇게하면 가장 민감한 병목 현상 중 하나 인 경향이있는 IO에 영향이 있는지 알 수 있습니다. 메모리 사용량을 테스트하는 것은 더 어렵고 철저하게 테스트하는 것은 어렵습니다. 잠재적 인 최악의 경우를 테스트하는 것이 좋습니다 (메모리 결과에 중간 결과가 많은 쿼리, 큰 임시 테이블에 대한 설명 확인 등).

테이블에 많은 행이 없을 것이라는 것을 알고 있다면 조인, 인덱스 (특히 복합, 고유) 등에 열을 사용하지 않을 것이므로 많은 문제가 없을 것입니다.

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