빈 열 값이 채워진 열 값과 동일한 저장 공간을 차지합니까?


16

2 열이있는 테이블이 있습니다. 두 열의 유형이로 설정되어 varchar(38)있습니다. 열 중 하나에 대해 빈 값으로 행을 만들면 값이 비어 있지 않은 것과 동일한 저장 공간이 필요합니까?

다시 말해, MySQL은 행이 생성 될 때 열에 대한 저장 공간을 확보 할 것입니까 (유형에 따라 다름)?

답변:


11

로부터 REDUNDANT ROW_FORMAT에서 이노 디비 물리적 행 구조, bulletpoint # 7

SQL NULL 값은 레코드 디렉토리에 1-2 바이트를 예약합니다. 또한 SQL NULL 값은 가변 길이 column에 저장된 경우 레코드의 데이터 부분에 0 바이트를 예약합니다 . (A)에 고정 된 길이의 컬럼에는 레코드의 데이터 부분에서 열 고정 된 길이를 보유한다. NULL 값을위한 고정 공간을 예약하면 인덱스 페이지가 조각화되지 않고 열을 NULL에서 NULL이 아닌 값으로 갱신 할 수 있습니다.

로부터 COMPACT ROW_FORMAT에서 이노 디비 물리적 행 구조, bulletpoint # 2

레코드 헤더의 가변 길이 부분에는 NULL 열을 나타내는 비트 벡터가 포함됩니다. 인덱스에서 NULL 일 수있는 열의 수가 N이면 비트 벡터는 CEILING (N / 8) 바이트를 차지합니다 . 예를 들어, NULL 일 수있는 9-15 개의 열이있는 경우 비트 벡터는 2 바이트를 사용합니다. NULL 인 열은이 벡터의 비트 이외의 공간을 차지하지 않습니다 . 헤더의 가변 길이 부분에는 가변 길이 열의 길이도 포함됩니다. 각 길이는 열의 최대 길이에 따라 1-2 바이트를 사용합니다. 인덱스의 모든 열이 NOT NULL이고 고정 길이를 갖는 경우 레코드 헤더에는 가변 길이 부분이 없습니다.

이러한 글 머리 기호를 기준으로 다음 NULL은 열 스토리지에 대한 값이 차지하는 것입니다.

  • 가변 길이 : NULL 값 행 자체에서 저장 공간차지하지 않습니다.
  • 고정 길이 : 예약 된 공간을 차지합니다

이제 첫 번째 요점으로 인해 CHAR과 VARCHAR을 사용하도록 결정해야합니다.

NULL 값을위한 고정 공간을 예약하면 인덱스 페이지가 조각화되지 않고 NULL을 NULL이 아닌 값으로 갱신 할 수 있습니다.

이것은 NULL이 아닌 데이터가 저장되면 길을 따라 행이 조각화되는 것을 방지합니다. 이것은 MyISAM과 관련하여 이전에 논의한 내용입니다. 이전 게시물 참조 고정 크기 필드에서 CHAR vs VARCHAR을 사용하면 성능에 어떤 영향을 미칩니 까? .


안녕 롤란도, 내가 언급 한 또 다른 항목이 있었다, varchar (5)와 varchar (100) 형식 선언 사이의 메모리 할당의 차이. 또는 과잉 할당으로 인한 벌칙.
Craig Efrein

@CraigEfrein 답에 메모리 할당을 추가해야합니다. (BTW 나는 이미 당신의 답을
찬성했습니다

1
과도 할당에 대한 벌칙 SELECT은 임시 테이블을 작성해야하는 복합물이있는 경우 발생 합니다. 가능하다면, 그것은 사용 MEMORY및 변환 VARCHARCHARtmp를 테이블. 이제 VARCHAR(100)고정 된 100 (또는 300) 바이트를 사용하므로 쿼리 속도가 느려질 수 있습니다.
Rick James

@RolandoMySQLDBA, 귀하의 답변에 설명 된 동작은 Mysql 5.7 DYNAMIC 및 COMPACT 행 형식에 적용 가능합니까?
Dinesh Kumar

@DineshKumar이 단락은 여전히 ​​5.7 / 8.0 문서에 있습니다. DYNAMIC에 대해서는 dev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.html 을 참조하십시오 .
RolandoMySQLDBA

8

varchar 열에 정의한 길이에 관계없이 빈 열에 사용 된 저장 공간은 동일합니다.

CHAR 및 VARCHAR 유형

여기에 이미지 설명을 입력하십시오

이것은 varchar 열에 사용 된 공간 만 처리하며 행, 인덱스, 기본 키 및 기타 열에 사용 된 총 저장 공간은 고려하지 않습니다.

ypercube가 그의 의견에서 언급했듯이, 적어도 하나의 nullable 열이 존재할 때 행 저장소 전체에 대한 추가 고려 사항이 있습니다.

Innodb 물리적 행 구조

레코드 헤더의 가변 길이 부분에는 NULL 열을 나타내는 비트 벡터가 포함됩니다. NULL 일 수있는 9-15 개의 열이있는 경우 비트 벡터는 2 바이트를 사용합니다.)

...

헤더의 가변 길이 부분에는 가변 길이 열의 길이도 포함됩니다. 각 길이는 열의 최대 길이에 따라 1 바이트 또는 2 바이트를 사용합니다. 인덱스의 모든 열이 NOT NULL이고 고정 길이를 갖는 경우 레코드 헤더에는 가변 길이 부분이 없습니다.

그리고 예, 선택한 유형에 따라 사용 된 저장 공간이 고정적이거나 가변적이며 데이터 정렬 및 엔진과 같은 다른 요소입니다.

MySQL은 데이터 스토리지 최적화에 대한 권장 사항을 제시합니다. 데이터 크기 최적화

최신 정보

varchar에 대한 추가 고려 사항 중 하나는 메모리입니다. MySQL에서는 가변 길이 열의 크기를 가능한 한 제한하는 것이 중요합니다. 열이 가변적이고 사용되는 저장 공간이 가변적이지만 MySQL은 값을 저장하기 위해 고정 청크에 메모리를 할당합니다. 예를 들어 varchar (200)은 varchar (5)보다 더 많은 메모리를 사용합니다. 이는 저장 공간 문제가 아니지만 열을 정의 할 때 고려해야 할 사항입니다.


위의 숫자는 CHARACTER SETlatin1 또는 ascii를 가정 합니다. utf8의 경우, 필요한 스토리지 CHAR(4)는 12입니다.
Rick James
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.