파티셔닝 (Partitioning)이란 무엇인가?
파티셔닝은 대규모 테이블, 인덱스 또는 인덱스 구성 테이블을 더 작고 관리하기 쉬운 조각(파티션)으로 물리적으로 분할하는 데이터베이스 설계 기술입니다. 각 파티션은 독립적인 데이터베이스 객체처럼 관리될 수 있으며, 필요에 따라 개별적으로 백업, 복구, 인덱싱, 튜닝할 수 있습니다.
파티셔닝의 장점
- 성능 향상: 쿼리가 필요한 데이터만 스캔하므로 쿼리 성능이 향상됩니다.
- 관리 용이성: 대규모 테이블을 작은 파티션으로 분할하여 관리 및 유지 보수가 용이합니다.
- 가용성 향상: 특정 파티션에 문제가 발생해도 전체 테이블에 영향을 미치지 않아 가용성이 향상됩니다.
- 병렬 처리: 파티션별로 병렬 처리를 수행하여 데이터 로드 및 쿼리 성능을 향상시킬 수 있습니다.
- 스토리지 관리: 파티션을 테이블스페이스에 분산하여 스토리지 관리를 최적화할 수 있습니다.
파티셔닝의 유형
오라클 데이터베이스는 다양한 파티셔닝 유형을 제공하며, 각 유형은 특정 요구 사항에 적합합니다.
- 범위 파티셔닝 (Range Partitioning): 열 값의 범위를 기준으로 파티션을 분할합니다.
- 해시 파티셔닝 (Hash Partitioning): 해시 함수를 사용하여 파티션을 분할합니다.
- 리스트 파티셔닝 (List Partitioning): 특정 열 값의 리스트를 기준으로 파티션을 분할합니다.
- 컴포지트 파티셔닝 (Composite Partitioning): 범위, 해시, 리스트 파티셔닝과 같은 두 개 이상의 파티셔닝 방법을 결합합니다.
- 인터벌 파티셔닝 (Interval Partitioning): 범위 파티셔닝의 자동화된 형태이며, 지정된 간격으로 파티션을 자동으로 생성합니다.
- 참조 파티셔닝 (Reference Partitioning): 자식 테이블을 부모 테이블의 파티션 구조와 동일하게 만듭니다.
- 시스템 파티셔닝 (System Partitioning): 응용 프로그램이 데이터가 저장될 파티션을 제어합니다.
파티셔닝 구현 예시
다음은 범위 파티셔닝을 사용하여 SALES
테이블을 분할하는 예시입니다. 이 테이블은 SALE_DATE
열을 기준으로 연도별로 분할됩니다.
CREATE TABLE SALES (
SALE_ID NUMBER,
SALE_DATE DATE,
PRODUCT_ID NUMBER,
AMOUNT NUMBER
) PARTITION BY RANGE (SALE_DATE) (
PARTITION SALES_Q1_2023 VALUES LESS THAN (TO_DATE('2023-04-01', 'YYYY-MM-DD')),
PARTITION SALES_Q2_2023 VALUES LESS THAN (TO_DATE('2023-07-01', 'YYYY-MM-DD')),
PARTITION SALES_Q3_2023 VALUES LESS THAN (TO_DATE('2023-10-01', 'YYYY-MM-DD')),
PARTITION SALES_Q4_2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD'))
);
이 예제에서는 SALES
테이블을 생성하고 SALE_DATE
열을 기준으로 파티셔닝합니다. VALUES LESS THAN 절은 각 파티션에 저장될 데이터의 범위를 지정합니다.
실무 적용 시 고려 사항
파티셔닝을 구현할 때는 다음과 같은 사항을 고려해야 합니다:
- 파티셔닝 키 선택: 쿼리 패턴과 데이터 분포를 고려하여 적절한 파티셔닝 키를 선택해야 합니다.
- 파티션 수 결정: 너무 많은 파티션은 관리 오버헤드를 증가시키고, 너무 적은 파티션은 성능 향상을 제한할 수 있습니다.
- 인덱싱 전략: 파티션된 테이블에 대한 인덱스를 생성할 때는 로컬 인덱스와 글로벌 인덱스 중에서 선택해야 합니다. 로컬 인덱스는 각 파티션에 대해 생성되고, 글로벌 인덱스는 전체 테이블에 대해 생성됩니다.
- 유지 보수: 파티션 분할, 병합, 삭제와 같은 유지 보수 작업을 정기적으로 수행해야 합니다.
- 백업 및 복구: 파티션을 개별적으로 백업 및 복구할 수 있으므로, 백업 및 복구 전략을 신중하게 계획해야 합니다.
다양한 파티셔닝 예시 코드 및 실행 결과
1. 범위 파티셔닝 예시
CREATE TABLE employees (
employee_id NUMBER,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
hire_date DATE,
salary NUMBER
) PARTITION BY RANGE (hire_date) (
PARTITION employees_y2018 VALUES LESS THAN (TO_DATE('2019-01-01', 'YYYY-MM-DD')),
PARTITION employees_y2019 VALUES LESS THAN (TO_DATE('2020-01-01', 'YYYY-MM-DD')),
PARTITION employees_y2020 VALUES LESS THAN (TO_DATE('2021-01-01', 'YYYY-MM-DD')),
PARTITION employees_future VALUES LESS THAN (MAXVALUE)
);
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary) VALUES (1, 'John', 'Doe', TO_DATE('2018-05-15', 'YYYY-MM-DD'), 50000);
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary) VALUES (2, 'Jane', 'Smith', TO_DATE('2019-10-20', 'YYYY-MM-DD'), 60000);
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary) VALUES (3, 'Mike', 'Brown', TO_DATE('2020-03-25', 'YYYY-MM-DD'), 70000);
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary) VALUES (4, 'Lisa', 'Kim', TO_DATE('2021-07-10', 'YYYY-MM-DD'), 80000);
SELECT partition_name, high_value
FROM user_tab_partitions
WHERE table_name = 'EMPLOYEES';
실행 결과:
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
EMPLOYEES_Y2018 TO_DATE(' 2019-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
EMPLOYEES_Y2019 TO_DATE(' 2020-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
EMPLOYEES_Y2020 TO_DATE(' 2021-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
EMPLOYEES_FUTURE MAXVALUE
2. 해시 파티셔닝 예시
CREATE TABLE orders (
order_id NUMBER,
customer_id NUMBER,
order_date DATE,
total_amount NUMBER
) PARTITION BY HASH (customer_id)
PARTITIONS 4;
INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES (1, 101, SYSDATE, 100);
INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES (2, 202, SYSDATE, 200);
INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES (3, 303, SYSDATE, 300);
INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES (4, 404, SYSDATE, 400);
SELECT partition_name
FROM user_tab_partitions
WHERE table_name = 'ORDERS';
실행 결과: (실행 결과는 해시 함수에 따라 달라지므로, 실제 파티션 이름은 다를 수 있습니다.)
PARTITION_NAME
------------------------------
SYS_P311
SYS_P312
SYS_P313
SYS_P314
3. 리스트 파티셔닝 예시
CREATE TABLE products (
product_id NUMBER,
product_name VARCHAR2(50),
category VARCHAR2(50),
price NUMBER
) PARTITION BY LIST (category) (
PARTITION products_electronics VALUES ('Electronics'),
PARTITION products_clothing VALUES ('Clothing'),
PARTITION products_books VALUES ('Books'),
PARTITION products_other VALUES (DEFAULT)
);
INSERT INTO products (product_id, product_name, category, price) VALUES (1, 'Laptop', 'Electronics', 1200);
INSERT INTO products (product_id, product_name, category, price) VALUES (2, 'T-Shirt', 'Clothing', 25);
INSERT INTO products (product_id, product_name, category, price) VALUES (3, 'Oracle DBA Guide', 'Books', 50);
INSERT INTO products (product_id, product_name, category, price) VALUES (4, 'Coffee Mug', 'Other', 10);
SELECT partition_name, high_value
FROM user_tab_partitions
WHERE table_name = 'PRODUCTS';
실행 결과:
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
PRODUCTS_ELECTRONICS 'Electronics'
PRODUCTS_CLOTHING 'Clothing'
PRODUCTS_BOOKS 'Books'
PRODUCTS_OTHER DEFAULT
파티셔닝 관련 주요 팁
- 파티션 프루닝 (Partition Pruning): 오라클 옵티마이저는 쿼리에 필요한 파티션만 액세스하도록 자동으로 쿼리를 최적화합니다. 이를 파티션 프루닝이라고 합니다. 파티션 프루닝을 활용하려면 WHERE 절에 파티셔닝 키를 포함해야 합니다.
- 파티션 유지 보수 작업: 정기적인 파티션 유지 보수 작업을 통해 데이터베이스 성능을 최적화할 수 있습니다. 파티션 분할(Split Partition), 병합(Merge Partition), 교환(Exchange Partition) 등의 작업을 통해 데이터 분포 및 저장 방식을 관리할 수 있습니다.
- 온라인 재정의 (Online Redefinition): 오라클은 DBMS_REDEFINITION 패키지를 통해 테이블 구조를 변경하면서도 서비스를 중단하지 않고 온라인으로 재정의할 수 있습니다. 이는 파티셔닝 전략을 변경하거나 테이블 스키마를 업데이트할 때 유용합니다.
결론
파티셔닝은 오라클 데이터베이스에서 성능, 관리 용이성 및 가용성을 향상시키는 데 유용한 기술입니다. 파티셔닝 유형을 신중하게 선택하고, 적절한 유지 보수 작업을 수행하면 데이터베이스 성능을 크게 향상시킬 수 있습니다.