현재 선택한 SQL 과정

SQLP 이론 학습

이론 목록으로 돌아가기

파티션 설계의 기본: Range·List·Hash·Composite·Interval·Reference

대용량 Object를 Segment 단위로 나누는 목적과 업무 Access·관리 패턴에 맞는 Partition Key 선택을 학습합니다.

예상 읽기 25

핵심 요약

파티셔닝은 하나의 큰 Table 또는 Index를 여러 Partition이라는 독립 관리 단위로 나누면서도 애플리케이션에는 하나의 논리 객체처럼 보이게 하는 물리 설계입니다. 데이터가 저장된 각 Partition은 일반적으로 별도의 Segment를 가지지만, Deferred Segment Creation이 적용된 빈 Partition은 실제 Segment가 아직 할당되지 않을 수 있습니다. 따라서 파티션은 논리적 분할 단위이고 Segment는 실제 저장 공간 단위라는 차이를 먼저 이해해야 합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
성능
→ Partition Key Predicate로 불필요한 Partition을 제거하는 Pruning

관리성·가용성
→ Load·Exchange·Drop·Move·Compression·Backup·Recovery를 Partition 단위로 수행

확장성
→ Parallel Processing과 Partition-Wise Join의 작업 단위 제공

파티션 수를 늘리는 것 자체는 목적이 아닙니다. 가장 중요한 결정은 Partition Key, 경계, Partition 수, Index 구조이며 다음 요구를 함께 만족해야 합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
조회 Predicate
+ 데이터 증가 방향
+ 보관·삭제·적재 단위
+ 조인 Key와 병렬 처리
+ 값 편중과 Hotspot
+ 운영 복잡도

SQL이 Partition Key와 연결되지 않거나 Partition Key에 불필요한 함수·암시적 형변환을 적용하면 많은 Partition을 읽을 수 있습니다. 파티션 테이블이라는 사실만으로 조회가 자동으로 빨라지는 것은 아니며, 실행계획의 PSTART, PSTOP, Partition Iterator와 실제 I/O를 확인해야 합니다.

학습 목표

이 이론을 학습한 뒤에는 다음을 설명할 수 있어야 합니다.

  1. 논리 Table, Partition, Segment의 관계를 설명한다.
  2. 성능·관리성·가용성·확장성 목적을 구분해 Partitioning 필요성을 판단한다.
  3. Range·List·Hash Partitioning의 배치 원리와 적합한 Predicate를 구분한다.
  4. VALUES LESS THAN, MAXVALUE, DEFAULT의 경계와 NULL 처리 의미를 설명한다.
  5. Composite Partitioning에서 Partition Key와 Subpartition Key의 역할을 설명한다.
  6. Interval Partitioning의 Transition Point와 자동 생성 범위를 설명한다.
  7. Reference Partitioning의 Partitioning Referential Constraint 조건을 이해한다.
  8. 정적·동적 Partition Pruning과 PSTART·PSTOP을 해석한다.
  9. Local Prefixed·Local Nonprefixed·Global Index의 Trade-off를 판단한다.
  10. 너무 적거나 너무 많은 Partition이 만드는 성능·운영 비용을 판단한다.

1. Partition과 Segment를 구분한다

일반 Heap Table은 보통 하나의 Table Segment에 Row를 저장합니다. Partitioned Table은 같은 논리 Table의 Row를 Partition Key에 따라 여러 Partition에 나눕니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
논리 객체: SALES

Partition
├─ P202501
├─ P202502
├─ P202503
└─ P_MAX

Partition은 독립적으로 관리하고 접근할 수 있는 논리적 조각입니다. 데이터가 저장되면 각 Partition이 독립 Segment를 가지는 것이 일반적이지만, 빈 Partition에 Deferred Segment Creation이 적용되면 첫 Row가 들어오기 전까지 Segment가 없을 수 있습니다.

애플리케이션은 보통 Partition 이름이 아니라 Table 이름을 조회합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT SUM(amount)
FROM   sales
WHERE  sale_date >= DATE '2025-02-01'
  AND  sale_date <  DATE '2025-03-01';

Optimizer는 Predicate와 Partition 정의를 비교해 읽지 않아도 되는 Partition을 제거하고, 선택된 Partition 내부에서 Full Scan·Index Scan 등의 Access Path를 다시 선택합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Partition Pruning
→ 어떤 Partition을 읽을지 결정

Access Path
→ 선택된 Partition 안을 어떤 방식으로 읽을지 결정

파티셔닝은 Index를 대체하지 않습니다. Pruning으로 Partition 수를 줄여도 남은 Partition의 Row 수가 많으면 적절한 Index나 Full Scan·Parallel Scan 판단이 별도로 필요합니다.


2. Partition Key를 고르는 기준

Partition Key는 Cardinality나 검색 빈도 한 가지 기준으로 정하지 않습니다. 다음 질문을 함께 검토합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
1. 데이터는 어떤 방향과 단위로 증가하는가?
2. 오래된 데이터는 어떤 단위로 삭제·보관하는가?
3. 대량 적재·교체·검증은 어떤 단위로 수행하는가?
4. 큰 조회는 어떤 Predicate로 범위를 줄이는가?
5. 큰 Table끼리 주로 어떤 Key로 조인하는가?
6. 특정 값이나 기간에 Row가 몰리는가?
7. Local·Global Index 운영을 감당할 수 있는가?
8. Partition 수와 통계·Backup·DDL 복잡도를 감당할 수 있는가?

예를 들어 주문 이력을 매월 적재하고 5년이 지난 월 데이터를 제거한다면 ORDER_DATE 월별 Range Partition이 자연스럽습니다. 반대로 고객번호 단건 조회가 대부분이고 날짜 조건이 거의 없다면 날짜 Range Partition만으로는 Local Nonprefixed Index의 여러 Partition을 반복 Probe할 수 있으므로 Global Index 또는 다른 설계를 비교해야 합니다.

좋은 Partition Key는 단순히 자주 검색되는 Column이 아니라 조회와 데이터 생명주기를 같은 물리 단위로 정렬하는 Column입니다.


3. Range Partitioning과 경계

Range Partitioning은 연속된 값의 범위로 Row를 나눕니다. 날짜·일시·순번처럼 증가 방향과 보관 주기가 명확한 데이터에 자주 사용합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE TABLE sales (
    sale_id     NUMBER       NOT NULL,
    sale_date   DATE         NOT NULL,
    customer_id NUMBER       NOT NULL,
    amount      NUMBER
)
PARTITION BY RANGE (sale_date) (
    PARTITION p202501 VALUES LESS THAN (DATE '2025-02-01'),
    PARTITION p202502 VALUES LESS THAN (DATE '2025-03-01'),
    PARTITION p202503 VALUES LESS THAN (DATE '2025-04-01'),
    PARTITION pmax    VALUES LESS THAN (MAXVALUE)
);

3.1 VALUES LESS THAN은 상한 미포함이다

각 경계는 포함되지 않는 상한입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
P202501
sale_date < 2025-02-01

P202502
2025-02-01 <= sale_date < 2025-03-01

날짜 조회도 같은 반개구간으로 작성하면 시간 정밀도와 달 길이에 따른 경계 오류를 줄일 수 있습니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE sale_date >= DATE '2025-02-01'
  AND sale_date <  DATE '2025-03-01'

다음 방식은 DATE에서는 초 단위 끝을 계산해야 하고 TIMESTAMP에서는 더 정밀한 Fractional Second를 누락할 수 있으며, 월 길이에 따라 유지하기 어렵습니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE sale_date BETWEEN DATE '2025-02-01'
                    AND DATE '2025-02-28' + (86399 / 86400)

3.2 MAXVALUE와 NULL

MAXVALUE는 실제 저장값이 아니라 모든 가능한 Partition Key보다 높게 정렬되는 가상 상한입니다. Oracle의 Range Partition 의미에서는 NULL보다도 높게 정렬되므로, 최고 Partition이 MAXVALUE이면 Range Key의 NULL도 그 Partition에 들어갈 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
MAXVALUE의 역할
→ 아직 정의하지 않은 미래 값 수용
→ 최고 범위를 넘어서는 값의 Insert 오류 방지
→ Range Key NULL도 최고 Partition에 수용 가능

따라서 MAXVALUE Partition을 단순한 미래 월 임시 공간으로만 보지 말고 Row 수, NULL 수, 신규 경계 Split 정책을 함께 모니터링해야 합니다. 영구적인 Catch-All로 방치하면 큰 Segment와 편중이 생길 수 있습니다.


4. List Partitioning과 DEFAULT

List Partitioning은 연속 범위가 아니라 명시적인 값 집합으로 Row를 나눕니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE TABLE customer_activity (
    activity_id NUMBER,
    region_code VARCHAR2(10),
    activity_ts TIMESTAMP
)
PARTITION BY LIST (region_code) (
    PARTITION p_korea VALUES ('KR'),
    PARTITION p_japan VALUES ('JP'),
    PARTITION p_usa   VALUES ('US'),
    PARTITION p_other VALUES (DEFAULT)
);

대표 적용 기준은 다음과 같습니다.

  • 국가·지역·법인·업무 상태처럼 값 집합이 명확함
  • 그룹별 Tablespace·Compression·보관 정책이 다름
  • 특정 값 그룹을 독립적으로 적재·삭제·교체해야 함

DEFAULT Partition은 다른 List Partition에 매핑되지 않는 값을 받아 Insert 오류를 줄입니다. 그러나 신규 코드, 오타, NULL 등의 예외 값이 계속 모이면 데이터 품질 문제를 숨길 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
DEFAULT Partition 운영
→ Row 수와 값 분포 점검
→ 신규·오류 코드 식별
→ 정식 Partition 추가 여부 판단
→ 필요하면 DEFAULT Partition Split

List Partition은 업무 분류가 바뀔 때 Partition 정의 변경이 필요할 수 있으므로 코드 체계 변경 절차도 설계해야 합니다.


5. Hash Partitioning: 여러 Key를 분산한다

Hash Partitioning은 Oracle의 내부 Hash 함수 결과를 이용해 Row를 여러 Partition에 배치합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE TABLE account_txn (
    txn_id     NUMBER,
    account_id NUMBER,
    txn_ts     TIMESTAMP,
    amount     NUMBER
)
PARTITION BY HASH (account_id)
PARTITIONS 16;
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
account_id 값
→ Oracle Hash 함수
→ P1·P2·...·P16 중 하나

Hash Partitioning의 목표는 업무적으로 읽기 쉬운 범위를 만드는 것이 아니라 서로 다른 Key 값을 여러 Partition에 비교적 균등하게 분산하는 것입니다.

5.1 동일한 단일 Hot Key는 나뉘지 않는다

동일한 account_id 값은 같은 Hash 결과를 가지므로 같은 Partition으로 매핑됩니다. 따라서 하나의 인기 고객이 대부분의 Row를 생성한다면 Partition 수를 늘려도 그 단일 Key의 Row는 여러 Partition으로 자동 분할되지 않습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
많은 서로 다른 Key 값
→ 여러 Hash Partition으로 분산 가능

동일한 단일 Hot Key
→ 같은 Hash Partition에 집중

원본 Key가 단조 증가하더라도 값 자체가 다양하면 여러 Hash Partition으로 분산될 수 있지만, Key 값별 Row 수가 심하게 다르면 편중은 남습니다. Partition별 Row 수와 Block 수를 반드시 측정해야 합니다.

5.2 Pruning에 유리한 Predicate

Hash Partition에서는 Partition Key의 등치 또는 IN 목록 Predicate가 Pruning에 사용됩니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE account_id = :account_id
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE account_id IN (:id1, :id2, :id3)

account_id BETWEEN 100 AND 200 같은 범위는 연속 Partition 범위로 매핑되지 않으므로 Range Partition처럼 몇 개의 인접 Partition만 선택하는 근거가 되지 않습니다.

5.3 Partition 수

Oracle 공식 권고는 Hash 데이터 분포를 최적화하기 위해 Partition 또는 Hash Subpartition 수를 2의 거듭제곱으로 구성하는 것입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
권장 후보
2, 4, 8, 16, 32, ...

다만 2의 거듭제곱을 사용한다고 데이터 편중이 자동으로 사라지는 것은 아닙니다. Key의 NDV, 값별 Row 수, 병렬도, Partition 크기와 운영 비용을 함께 측정해야 합니다.


6. Composite Partitioning과 두 단계 Pruning

Composite Partitioning은 Table을 한 기준으로 Partition한 뒤 각 Partition을 다른 기준으로 다시 Subpartition합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
1단계 Partition Key
→ 주된 관리·보관·Pruning 축

2단계 Subpartition Key
→ 분산·조인·세부 관리 축

Oracle은 Range-Hash뿐 아니라 Range-List, Range-Range, List-Hash, List-List, List-Range, Hash-Hash, Hash-List, Hash-Range 등 다양한 조합을 지원합니다. 설계 목적이 없는 복합화는 Partition 수와 운영 복잡도만 늘릴 수 있습니다.

6.1 Range-Hash 예시

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE TABLE sales (
    sale_id     NUMBER,
    sale_date   DATE,
    customer_id NUMBER,
    amount      NUMBER
)
PARTITION BY RANGE (sale_date)
SUBPARTITION BY HASH (customer_id)
SUBPARTITIONS 8 (
    PARTITION p202501 VALUES LESS THAN (DATE '2025-02-01'),
    PARTITION p202502 VALUES LESS THAN (DATE '2025-03-01'),
    PARTITION pmax    VALUES LESS THAN (MAXVALUE)
);
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
sale_date Range
→ 월별 적재·삭제·Pruning

customer_id Hash
→ 월 내부의 여러 고객 Key 분산·병렬 처리·Partition-Wise Join 후보

SQL에 sale_date 조건만 있으면 주 Partition은 줄지만 선택된 각 Range Partition의 여러 Hash Subpartition을 읽을 수 있습니다. customer_id 등치 조건까지 있으면 각 Range Partition 안에서 관련 Hash Subpartition도 줄어들 수 있습니다.

6.2 Range-List 예시

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
월별 Range Partition
└─ 채널별 List Subpartition
   ├─ ONLINE
   ├─ STORE
   └─ PARTNER

월 단위 보관과 채널 단위 적재·관리 정책을 함께 적용할 때 적합할 수 있습니다. 두 번째 축이 실제 운영이나 조회에 사용되지 않으면 불필요한 Subpartition만 늘어납니다.


7. Interval Partitioning과 Transition Point

Interval Partitioning은 Range Partitioning의 확장입니다. 최소 하나의 Range Partition을 정의하고, 그 최고 상한을 Transition Point로 사용합니다. Transition Point를 넘는 값이 Insert되면 지정한 간격에 해당하는 Partition을 Oracle이 자동 생성합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE TABLE sales_interval (
    sale_id   NUMBER,
    sale_date DATE,
    amount    NUMBER
)
PARTITION BY RANGE (sale_date)
INTERVAL (NUMTOYMINTERVAL(1, 'MONTH')) (
    PARTITION p_before_2025
    VALUES LESS THAN (DATE '2025-01-01')
);
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
2025-01-01 미만
→ 사용자가 정의한 Range 영역

2025-01-01 이상
→ 월 간격의 Interval 영역
→ 해당 범위 Row가 처음 들어올 때 필요한 Partition 생성

중간 월에 데이터가 없으면 모든 빈 월 Partition을 미리 만들 필요는 없습니다. 예를 들어 7월 Row가 먼저 들어오면 7월에 해당하는 Interval Partition이 생성되며, 6월 Partition이 실제로 만들어졌는지와 관계없이 경계 계산은 월 간격을 따릅니다.

7.1 자동화 범위와 제약

Interval Partitioning은 미래 경계 생성을 자동화하지만 다음 전체 운영을 자동화하지는 않습니다.

  • 자동 생성 Partition의 System-generated 이름 확인 또는 Rename 정책
  • Tablespace·Compression 등 Default 속성
  • Local Index와 통계 수집
  • 오래된 Partition Drop·Archive 정책
  • Exchange·Backup·Recovery 절차
  • Interval 변경 시 기존 High Bound 정렬 여부

Interval Partitioning은 Partition Key Column을 하나만 지정할 수 있고 지원되는 데이터 타입에 제약이 있습니다. 또한 Interval Table에서는 미래 범위를 받기 위해 MAXVALUE Partition을 두는 방식과 개념이 다릅니다. 미래 Partition은 Insert 시 Interval 규칙으로 생성됩니다.


8. Reference Partitioning과 Referential Constraint

Reference Partitioning은 자식 Table이 자신의 Column을 직접 Partition Key로 선언하는 대신, 부모와의 Foreign Key 관계를 따라 부모의 Partition 배치를 상속하는 방식입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
ORDERS
→ order_date 기준 Range Partition

ORDER_ITEMS
→ ORDERS를 참조하는 FK를 Partitioning Referential Constraint로 사용
→ 부모 Row가 속한 Partition에 대응하는 자식 Partition에 배치
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE TABLE orders (
    order_id   NUMBER       NOT NULL,
    order_date DATE         NOT NULL,
    CONSTRAINT orders_pk PRIMARY KEY (order_id)
)
PARTITION BY RANGE (order_date) (
    PARTITION p202501 VALUES LESS THAN (DATE '2025-02-01'),
    PARTITION p202502 VALUES LESS THAN (DATE '2025-03-01')
);

CREATE TABLE order_items (
    order_item_id NUMBER NOT NULL,
    order_id      NUMBER NOT NULL,
    product_id    NUMBER,
    CONSTRAINT order_items_fk
        FOREIGN KEY (order_id)
        REFERENCES orders(order_id)
)
PARTITION BY REFERENCE (order_items_fk);

PARTITION BY REFERENCE에 지정하는 Referential Constraint는 Enabled이면서 Enforced 상태여야 합니다. 자식 Row의 Partition 배치는 단순히 FK Column 값의 범위를 직접 계산하는 것이 아니라, 참조하는 부모 Row가 속한 Partition을 따릅니다.

장점은 다음과 같습니다.

  • 부모·자식 기간 데이터의 대응 Partition 관리
  • Parent-Child Partition-Wise Join 후보
  • 자식 Table에 부모 날짜 Column을 중복 저장하지 않고 동일 경계 유지
  • 부모 Join 조건을 통한 자식 Reference Partition Pruning 가능

FK 상태, 부모·자식 Partition Maintenance Operation의 순서, Exchange·Drop 시 참조 무결성 영향을 운영 절차에 반영해야 합니다.


9. Partition Pruning과 실행계획

Partition Pruning은 Optimizer가 SQL의 FROM·WHERE 조건을 분석해 필요 없는 Partition을 Partition Access List에서 제외하는 기능입니다.

9.1 Pruning에 사용되는 Predicate

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Range·List Partition Key
→ Range, LIKE, Equality, IN-list Predicate 활용 가능

Hash Partition Key
→ Equality, IN-list Predicate 활용

Composite
→ 각 단계의 관련 Key Predicate로 Partition과 Subpartition Pruning

Partition Key에 함수나 변환을 적용하면 단순한 정적 Pruning이 제한되거나 Pruning 자체가 어려워질 수 있습니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
-- 경계와 직접 비교
WHERE sale_date >= DATE '2025-02-01'
  AND sale_date <  DATE '2025-03-01'
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
-- 단순 Range Key에 함수를 적용해 Pruning 기회를 약화할 수 있음
WHERE TRUNC(sale_date) = DATE '2025-02-01'

암시적 데이터 타입 변환도 피해야 합니다. 날짜 Literal·Bind의 타입을 Partition Key와 맞추고, 불가피한 표현식 기준 조회가 핵심이라면 Virtual Column 또는 Expression Partitioning 같은 별도 설계를 검토합니다.

9.2 정적 Pruning

Compile Time에 접근 Partition을 결정할 수 있으면 PSTARTPSTOP에 숫자 Partition 범위가 나타날 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
PARTITION RANGE SINGLE  PSTART 17  PSTOP 17
→ 17번 Partition 하나

PARTITION RANGE ITERATOR  PSTART 13  PSTOP 16
→ 13~16번 Partition 범위

9.3 동적 Pruning

Bind, Subquery, Star Transformation, Nested Loop 연계처럼 Runtime에 접근 Partition이 결정되면 PSTART·PSTOPKEY, KEY(I), KEY(SQ)와 같은 표식이 나타날 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
PSTART KEY(I), PSTOP KEY(I)
→ IN-list 또는 Runtime 값에 따른 동적 Pruning

KEY가 보인다고 Pruning이 실패한 것은 아닙니다. 실제 실행 시 결정되는 동적 Pruning일 수 있으므로 실제 Cursor와 Runtime 통계를 확인합니다. 반대로 PARTITION RANGE ALL은 실질적으로 모든 Partition을 접근한다는 의미입니다.

Interval Partition Table의 Full Scan Plan에서는 생성된 실제 Partition 수와 무관하게 PSTART=1, PSTOP=1048575로 표시될 수 있으므로 숫자만 보고 물리적으로 백만 개 Partition이 존재한다고 해석하면 안 됩니다.


10. Local·Global Index 설계

10.1 Local Index

Local Index는 Table Partition과 1:1로 대응하는 Equipartitioned Index입니다. Table Partition이 추가·삭제되면 대응 Index Partition도 함께 관리되므로 Partition Maintenance와 가용성 측면에서 유리합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Table P202501 ↔ Local Index P202501
Table P202502 ↔ Local Index P202502
  • Local Prefixed Index: Index 선두 Column에 Table Partition Key가 포함되는 구조
  • Local Nonprefixed Index: Index 선두가 다른 Column이며 Table Partition 경계는 그대로 따르는 구조

날짜 Range Partition Table에 (customer_id) Local Nonprefixed Index를 만들면 고객번호로 빠르게 찾을 수 있지만, SQL에 날짜 조건이 없으면 여러 Local Index Partition을 Probe할 수 있습니다.

Local Index로 Unique를 보장하려면 Table Partition Key가 Index Key Column에 포함되어야 합니다. Partition Key가 빠진 Unique Local Index는 전체 Partition을 가로지르는 유일성을 독립적으로 보장할 수 없기 때문입니다.

10.2 Global Index

Global Index는 Table Partition 경계와 독립적으로 전체 Table Row를 하나의 Index 구조 또는 별도의 Global Index Partition 경계로 관리합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
장점
→ 날짜 조건 없는 선택적 고객 단건 조회에 유리할 수 있음
→ Table Partition Key와 무관한 전역 유일성 지원 가능

비용
→ Partition Maintenance 시 영향 범위와 Index 유지관리 복잡도 증가 가능

따라서 Local이 항상 좋다 또는 Global이 항상 빠르다가 아니라 조회 패턴과 Drop·Exchange·Load 절차를 함께 비교해야 합니다.


11. Partition 수와 크기 결정

Partition을 너무 크게 만들면 다음 문제가 생길 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Pruning 후에도 읽는 Block이 많음
Load·Exchange·Drop 단위가 지나치게 큼
병렬 작업 분할 단위가 부족함
장애·복구 영향 단위가 큼

너무 작게 만들면 다음 비용이 증가합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Partition·Subpartition·Index Partition 수 증가
Data Dictionary·통계·Backup 관리 복잡도 증가
많은 Partition Iterator와 반복 Index Probe
작은 Segment 다수와 과도한 DDL 작업

적절한 크기는 고정 공식으로 정하지 않고 다음을 함께 측정합니다.

  • 한 번의 조회가 읽는 기간과 Partition 수
  • 적재·삭제·보관 주기
  • Partition별 Row 수와 Block 수
  • Parallel Degree와 실제 Slave 작업 분배
  • Local Index Partition 관리 시간
  • 통계 수집·Backup·Recovery 시간
  • DDL Lock과 운영 Window

Hash Partition 수의 2의 거듭제곱 권고도 이 측정과 함께 적용해야 하며, 필요 이상의 Partition을 만드는 근거로 사용하면 안 됩니다.


12. 설계 사례와 검증 절차

요구사항을 다음과 같이 가정합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
주문 데이터 10년 보관
월 5억 행 증가
5년 경과 데이터는 월 단위 삭제
최근 3개월 조회가 대부분
고객별 대량 집계와 병렬 조인이 많음
날짜 없는 고객 단건 조회도 일부 존재

후보 설계는 다음과 같습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Range Partition: order_date 월 단위
Hash Subpartition: customer_id, 후보 수는 2의 거듭제곱 기준으로 실측
Local Index: 월 단위 운영과 날짜 포함 조회 중심
Global Index: 날짜 없는 고선택도 고객 조회가 중요할 때 제한적으로 비교

진단 순서는 다음과 같습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
1. 업무 생명주기
→ 월 단위 보관·삭제이므로 order_date Range 후보

2. 분산과 조인
→ 여러 customer_id 값의 분산이 필요하므로 Hash Subpartition 후보

3. Hot Key 확인
→ 단일 고객에 Row가 몰리면 Hash만으로 해결되지 않음

4. SQL Predicate 확인
→ 날짜·고객 조건이 실제로 함께 사용되는지 확인

5. 실행계획 확인
→ PARTITION RANGE/HASH Operation, PSTART, PSTOP, Predicate 확인

6. 실제 실행 통계
→ Partition별 A-Rows·Buffers·A-Time과 병렬 작업 편중 확인

7. 운영 검증
→ Load·Exchange·Drop·Local/Global Index 유지·통계 수집 시간 측정

파티션 설계는 DDL을 작성하는 것으로 끝나지 않습니다. 대표 SQL과 대표 운영 작업을 실제 데이터 분포로 검증한 뒤 경계와 Index를 확정해야 합니다.


설계 점검표

점검 항목질문
객체Partition과 실제 Segment 할당 상태를 구분했는가?
Key조회·적재·삭제·조인 단위를 함께 반영했는가?
경계VALUES LESS THAN의 상한 미포함과 반개구간을 정확히 정의했는가?
예외MAXVALUE의 NULL과 DEFAULT의 신규·오류 값을 모니터링하는가?
Hash여러 Key 분산과 동일 단일 Hot Key 편중을 구분했는가?
Composite두 번째 Key가 실제 Pruning·조인·운영 목적을 가지는가?
IntervalTransition Point와 자동 생성 범위, 별도 보관 정책을 설계했는가?
ReferencePartitioning FK가 Enabled·Enforced이며 부모·자식 PMO 절차가 있는가?
PruningPSTART·PSTOP과 정적·동적 Pruning을 실제 Cursor에서 확인했는가?
Index날짜 없는 조회가 Local Index 전체 Probe를 만들지 않는가?
UniqueUnique Local Index에 Table Partition Key가 포함되어 있는가?
운영Add·Split·Exchange·Drop·통계·Backup·Recovery 절차가 준비됐는가?
병렬Partition 수와 크기가 DOP와 실제 작업 분배에 적절한가?
스스로 확인하기

개념 확인 문제

문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.

01Partition과 Segment는 어떤 차이가 있으며 빈 Partition에 Segment가 없을 수 있는 이유는 무엇인가?
정답 및 해설

Partition은 논리 Table을 나눈 독립 관리 단위이고 Segment는 실제 저장 공간입니다. Deferred Segment Creation이 적용된 빈 Partition은 첫 Row가 들어오기 전까지 Segment가 할당되지 않을 수 있습니다.

02Range Partition의 VALUES LESS THAN 경계값은 해당 Partition에 포함되는가?
정답 및 해설

포함되지 않습니다. VALUES LESS THAN (DATE '2025-03-01')은 2025-03-01보다 작은 값까지만 해당 Partition에 저장하며 경계값은 다음 Partition에 들어갑니다.

03MAXVALUE Partition이 미래 값뿐 아니라 NULL과도 관련되는 이유는 무엇인가?
정답 및 해설

MAXVALUE는 모든 가능한 Partition Key보다 높고 NULL보다도 높게 정렬되는 가상 상한이기 때문입니다. 최고 Range Partition이 MAXVALUE이면 미래 값뿐 아니라 Range Key NULL도 수용할 수 있어 NULL 수와 편중을 모니터링해야 합니다.

04List Partition의 DEFAULT Partition을 계속 방치할 때 생길 수 있는 문제는 무엇인가?
정답 및 해설

신규 코드·오타·NULL 같은 예외 값이 Catch-All Partition에 계속 쌓여 데이터 품질 문제와 편중을 숨길 수 있습니다. 값 분포를 점검하고 정식 Partition 추가 또는 DEFAULT Split을 검토합니다.

05Hash Partition이 여러 Key를 분산해도 동일한 단일 Hot Key 편중을 해결하지 못하는 이유는 무엇인가?
정답 및 해설

동일한 Key 값은 항상 같은 Hash 결과와 같은 Partition으로 매핑되기 때문입니다. Hash는 여러 서로 다른 Key 값을 분산하지만 하나의 인기 고객처럼 동일 Key의 Row를 여러 Partition으로 자동 분할하지 않습니다.

06Hash Partition 수를 설계할 때 Oracle이 권고하는 형태와 함께 측정해야 할 요소는 무엇인가?
정답 및 해설

Partition 또는 Hash Subpartition 수를 2의 거듭제곱으로 구성하는 것이 공식 권고입니다. 다만 Key NDV, 값별 Row 수, Partition별 Block 수, 병렬도와 운영 비용을 실제로 측정해야 합니다.

07Range-Hash Composite에서 날짜 조건만 있는 SQL과 날짜·고객 조건이 모두 있는 SQL의 Pruning 차이는 무엇인가?
정답 및 해설

날짜 조건만 있으면 Range Partition은 줄지만 선택된 Partition의 여러 Hash Subpartition을 읽을 수 있습니다. 날짜 조건과 고객 등치 조건이 모두 있으면 주 Partition과 각 주 Partition 안의 관련 Hash Subpartition까지 줄어들 수 있습니다.

08Interval Partitioning의 Transition Point와 자동 생성 범위는 무엇인가?
정답 및 해설

Transition Point는 사용자가 정의한 최고 Range Partition의 상한입니다. 그보다 큰 값이 Insert되면 지정한 Interval 간격에 해당하는 Partition을 필요할 때 자동 생성하지만 Drop·통계·Tablespace·Compression 같은 운영 정책은 별도입니다.

09Reference Partitioning에 지정하는 Foreign Key Constraint는 어떤 상태여야 하는가?
정답 및 해설

PARTITION BY REFERENCE에 지정한 Referential Constraint는 Enabled이면서 Enforced 상태여야 합니다. 자식 Row는 FK 값 자체의 범위를 직접 계산하는 것이 아니라 참조 부모 Row가 속한 Partition을 따라 배치됩니다.

10실행계획에서 숫자 PSTART/PSTOP과 KEY 표식은 각각 어떤 Pruning을 의미하며, 날짜 없는 고객 조회에서는 어떤 Index 구조를 비교해야 하는가?
정답 및 해설

숫자 범위는 Compile Time에 결정된 정적 Pruning, KEY 계열은 Runtime에 결정되는 동적 Pruning을 나타낼 수 있습니다. 날짜 조건 없는 고객 조회가 많으면 Local Nonprefixed Index의 여러 Partition Probe 비용과 Global Index의 조회·유지 비용을 비교합니다.