varchar (n)의 오버 헤드는 무엇입니까?


15

Postgres 문서 에서 varchar(n)유형 에 관한 이 조각의 의미를 묻고 싶었습니다 .

짧은 문자열 (최대 126 바이트)에 대한 스토리지 요구 사항은 1 바이트 + 실제 문자열이며 문자의 경우 공백을 포함합니다. 긴 문자열은 1 대신 4 바이트의 오버 헤드를 갖습니다.

varchar(255)필드 가 있다고 가정 해 봅시다 . 그리고 지금, 다음 진술 :

  • 이 필드에 10 바이트의 문자열이 있으면 오버 헤드는 1 바이트입니다. 따라서 문자열은 11 바이트를 사용합니다.
  • 필드가 140 바이트를 사용하여 문자열을 보유하면 오버 헤드는 4 바이트입니다. 따라서 문자열은 144 바이트를 사용합니다.

위의 진술이 사실입니까? 여기에 누군가가 문서 나와 같은 방식으로 이해하지만, 여기에 누군가가 오버 헤드가 항상 4 바이트 상태 여기에 ?

답변:


19

당연히 매뉴얼이 옳습니다. 그러나 더 많은 것이 있습니다.

하나의 경우, 디스크의 크기 ( 실제로 디스크에 저장되지 않은 경우에도 모든 테이블 에서)는 메모리의 크기 다를 수 있습니다 . 디스크 에서 매뉴얼에 명시된대로 varchar최대 126 바이트의 짧은 값에 대한 오버 헤드 가 1 바이트 로 줄어 듭니다 . 그러나 메모리 의 오버 헤드 는 항상 4 바이트입니다 (한 번 개별 값이 추출 됨).

동일은 마찬가지입니다 text, varchar, varchar(n)또는char(n) -이 제외 char(n)되는 빈 - 패딩 n문자와 일반적으로 사용하지 않습니다. 유효 크기는 바이트가 n아니라 최대 문자를 나타내 므로 멀티 바이트 인코딩에서 여전히 다를 수 있습니다 .

최대 n길이의 문자 (바이트가 아님)

그들 모두는 varlena내부적으로 사용 합니다.
"char"(큰 따옴표 포함)는 다른 생물이며 항상 단일 바이트를 차지합니다.
형식화되지 않은 문자열 리터럴 ( 'foo')에는 단일 바이트 오버 헤드가 있습니다. 입력 된 값과 혼동하지 마십시오!

로 테스트하십시오 pg_column_size().

CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');

SELECT pg_column_size(id)        AS id
     , pg_column_size(v_small)   AS v_small
     , pg_column_size(v_big)     AS v_big
     , pg_column_size(t)         AS t
FROM   t
UNION ALL  -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
     , pg_column_size('foo'::varchar)
     , pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
     , pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));

 id | v_small | v_big |  t
----+---------+-------+-----
  4 |       4 |   144 | 176
  4 |       7 |   144 | 176

보다시피 :

  • 3 바이트 스트링 '갑'은 점유 4 바이트 디스크 및 7 바이트 RAM (오버 헤드이므로 1 바이트 대 4 바이트)에있다.
  • 140 바이트 문자열 '123 ...'은 디스크와 RAM 모두에서 144 바이트를 차지하므로 항상 4 바이트의 오버 헤드가 발생합니다.
  • 스토리지 integer에는 오버 헤드가 없지만 패딩이 발생할 수있는 정렬 요구 사항이 있습니다.
  • 행은 튜플 헤더에 대한 추가 오버 헤드가 24 바이트이며 페이지 헤더의 항목 포인터에 대해 튜플 당 추가 4 바이트가 있습니다.
  • 그리고 마지막으로 : varchar행 크기에서 볼 수 있듯이 작은 행의 오버 헤드 는 여전히 1 바이트이지만 행에서 추출되지 않았습니다. (따라서 때로는 전체 행을 선택하는 것이 조금 더 빠릅니다.)

관련 :


1
1 바이트 오버 헤드가 여전히 인덱스에서 1 바이트입니까?
dvtan

1
@dtgq : 인덱스는 테이블처럼 데이터를 저장하므로 예.
Erwin Brandstetter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.