[PostgreSQL] Nested Partition , 파티션 속에 파티션 넣기

식빵·2025년 6월 13일
0

postgresql-memo

목록 보기
37/37
post-thumbnail

가끔 너무 큰 테이블을 파티션했음에도 불구하고,
여전히 자식 테이블이 너무 큰 경우가 있습니다.

이럴 때는 Nested Partition 을 한번 고려해보시기 바랍니다.
Nested Partition 은 파티션을 낸 하위 테이블을 다시 파티션 내는 방법입니다.

지금부터 간단한 예시를 통해서 그 방법을 공유합니다.


🐣 Nested Partition

-- 가장 최상위 레벨의 논리 테이블
CREATE TABLE data_totals (
   id int NOT NULL 
)
PARTITION BY RANGE (id);


-- 최상위 바로 아래 중간 레벨의 논리 테이블
CREATE TABLE data_partition_1
PARTITION OF data_totals
FOR VALUES FROM (0) TO (10000)
PARTITION BY RANGE (id);


-- 중간 레벨의 논리 테이블에 붙은 실제 물리 테이블
create table data_partition_1_0
partition of data_partition_1
for values from (0) TO (2500);

create table data_partition_1_1
partition of data_partition_1
for values from (2500) TO (5000);

create table data_partition_1_2
partition of data_partition_1
for values from (5000) TO (7500);

create table data_partition_1_3
partition of data_partition_1
for values from (7500) TO (10000);

-- 예시 데이터 입력:
-- [ 0 <= x < 10000 ] 범위의 정수 데이터를 5000 개 랜덤 생성하여 insert
insert into data_totals(id)
select FLOOR(random() * 10000) as int 
from generate_series(0, 5000) as t

-- 인덱스 생성: 이러면 맨 끝에 있는 자식 테이블(=물리 테이블)에 인덱스가 생깁니다.
create index on data_totals(id);

IDE 로 테이블 형태를 확인해보면 다음과 같습니다.

  • 정상적으로 nested 된 것을 확인할 수 있습니다.

이번에는 (논리/물리) 파티션 테이블들의 메타정보를 조회해보겠습니다.

select
    pg_size_pretty(pg_total_relation_size(oid)) as pretty_size,
    relname,
    case
        when relkind = 'r' then '일반 테이블'
        when relkind = 'i' then '인덱스'
        when relkind = 'S' then '시퀀스'
        when relkind = 'v' then '뷰'
        when relkind = 'm' then '마테리얼라이즈드 뷰'
        when relkind = 'c' then '컴파일된 테이블 함수'
        when relkind = 'f' then '컴파일된 외부 테이블 함수'
        when relkind = 'p' then '파티션'
        when relkind = 'I' then '파티션 인덱스'
        when relkind = 't' then 'TOAST 테이블'
        end reltype_nm
from pg_class
where relname like 'data_partition%'
    or relname like 'data_total%'
order by 3, 2;
  • 최상위, 그리고 중간 논리 테이블/인덱스는 모두 크기가 0 bytes 인 것을 확인
  • 최하위 물리 테이블/인덱스는 모두 실제 크기를 갖는 것을 확인
  • 최상위 논리 테이블에 create index 를 수행했음에도, 최하위 물리 테이블에 모두
    index 가 생긴 것을 확인!

마지막으로 partition pruning 이 되는지 간단히 확인해보겠습니다.

explain analyse
select id
from data_totals
where id = 649
-- select id from data_totals limit 1;
-- 에서 나온 값을 where 절에 사용
  • 정확히 id=649 값이 소속된 RANGE 를 갖는 data_partition_1_0 테이블이 사용된 것을 확인!

이상으로 postgresql 에서 subpartition 하는 방법을 알아봤습니다.
이만 글을 마치도록 하겠습니다.



📝 참고한 링크

profile
백엔드 개발자로 일하고 있는 식빵(🍞)입니다.

0개의 댓글