Tối ưu hóa partition trong Oracle là một nghệ thuật quan trọng để xử lý dữ liệu lớn hiệu quả, giảm thời gian truy vấn, tối ưu lưu trữ và cải thiện khả năng bảo trì.

1. Chọn chiến lược phân vùng phù hợp
- Range Partitioning (Phân vùng theo khoảng giá trị) là kỹ thuật chia dữ liệu thành nhiều phần nhỏ dựa trên giá trị trong một cột cụ thể, thường là ngày tháng hoặc số. Kỹ thuật này rất phù hợp khi làm việc với dữ liệu chuỗi thời gian (time-series) — vốn thường có khối lượng lớn và tăng trưởng liên tục theo thời gian.
  Time-Series là gì?
  Time-series là chuỗi dữ liệu được ghi nhận theo trình tự thời gian, thường có khoảng cách thời gian đều nhau (ví dụ: mỗi phút, mỗi giờ, mỗi ngày...). Đây là loại dữ liệu phổ biến trong nhiều lĩnh vực như:
   + Tài chính: Giá cổ phiếu theo ngày, tỷ giá hối đoái.
   + Kinh tế: GDP theo quý, lạm phát theo tháng.
   + Kỹ thuật: Dữ liệu cảm biến thời gian thực.
   + Viễn thông: Lưu lượng mạng theo giờ.
   + Y tế: Nhịp tim, huyết áp theo thời gian.
  Ứng dụng phổ biến
   + Dự đoán giá trị tương lai (forecasting).
   + Phát hiện bất thường (anomaly detection).
   + Phân tích xu hướng, mùa vụ (trend and seasonality analysis).
   + Giám sát hệ thống và cảnh báo thời gian thực.
Ví  dụ:
CREATE TABLE sensor_data (
    sensor_id     NUMBER,
    record_date   DATE,
    temperature   NUMBER,
    humidity      NUMBER
)
PARTITION BY RANGE (record_date)
(
    PARTITION p_2024_q1 VALUES LESS THAN (TO_DATE('2024-04-01','YYYY-MM-DD')),
    PARTITION p_2024_q2 VALUES LESS THAN (TO_DATE('2024-07-01','YYYY-MM-DD')),
    PARTITION p_2024_q3 VALUES LESS THAN (TO_DATE('2024-10-01','YYYY-MM-DD')),
    PARTITION p_2024_q4 VALUES LESS THAN (TO_DATE('2025-01-01','YYYY-MM-DD')),
    PARTITION p_future  VALUES LESS THAN (MAXVALUE)
);
    Khi insert dữ liệu cảm biến, Oracle sẽ tự động định tuyến dữ liệu vào phân vùng phù hợp miễn là:
    + Cột phân vùng phải có giá trị (không phải NULL). Nếu có khả năng dữ liệu NULL, hãy thiết kế phân vùng riêng để chứa giá trị NULL (bằng cách dùng Subpartition hoặc Partition by List nếu cần).
    + Giá trị phải nằm trong khoảng giá trị định nghĩa của từng phân vùng.
- List Partitioning: Phân vùng theo danh sách giá trị cụ thể. Dùng khi dữ liệu theo nhóm cụ thể như chi nhánh, tỉnh/thành, vùng miền, quốc gia,...
Ví dụ:
    PARTITION BY LIST (region)
    (
      PARTITION asia VALUES ('VN', 'TH', 'ID'),
      PARTITION europe VALUES ('FR', 'DE', 'UK')
    )
- Hash Partitioning: Là kỹ thuật phân vùng dữ liệu bằng cách áp dụng một hàm băm lên giá trị của một hoặc nhiều cột, sau đó gán dữ liệu đến một phân vùng tương ứng. Kết quả là dữ liệu được phân bố đồng đều trên các phân vùng, giúp:
  + Tăng hiệu suất truy vấn song song (parallel query).
  + Tăng hiệu suất truy vấn trong môi trường có nhiều lượt truy cập đồng thời nhờ khả năng: Thực thi truy vấn trên nhiều phân vùng cùng lúc, mỗi phân vùng xử lý bởi một luồng hoặc tiến trình khác nhau.
  + Cân bằng tải khi dữ liệu không có quy luật rõ ràng theo giá trị.
  + Hạn chế hiện tượng “nóng phân vùng” (hot partition).
Ví dụ:
    CREATE TABLE customer_orders (
        order_id     NUMBER,
        customer_id  NUMBER,
        order_date   DATE,
        total_amount NUMBER
    )
    PARTITION BY HASH (customer_id)
    PARTITIONS 4;
Oracle sẽ tự động tính toán hàm băm dựa trên customer_id và gán dòng dữ liệu vào một trong 4 phân vùng (Oracle đặt tên tự động: SYS_P0, SYS_P1, ...).
- Composite Partitioning: Là loại phân vùng kết hợp hai cấp độ: Partition chính (primary) và subpartition phụ, cho phép tổ chức dữ liệu đa chiều cực kỳ linh hoạt và hiệu quả với dữ liệu lớn. Có các loại Composite Partitioning phổ biến:
Loại Composite Mô tả Ví dụ ứng dụng
Range-Hash Phân theo khoảng (range), rồi chia hash Theo tháng + phân tải theo ID
Range-List Phân theo khoảng, rồi chia theo danh sách Theo tháng + phân vùng theo tỉnh
List-Range Phân theo danh sách, rồi chia theo khoảng Theo quốc gia + chia theo năm
List-Hash Phân theo danh sách, rồi chia theo hash Theo khu vực + chia đều theo ID
Interval-Range/List Dùng khi dữ liệu phát sinh động (Oracle 11g+) Log động theo ngày + chia theo tỉnh

Ví dụ 1: Range-Hash Partitioning
Phân vùng theo thời gian, subpartition theo store_id (chia đều tải):
CREATE TABLE sales (
  sale_id     NUMBER,
  sale_date   DATE,
  store_id    NUMBER,
  amount      NUMBER
)
PARTITION BY RANGE (sale_date)
SUBPARTITION BY HASH (store_id)
SUBPARTITIONS 4
(
  PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01','YYYY-MM-DD')),
  PARTITION p2024 VALUES LESS THAN (MAXVALUE)
);
Ví dụ 2: Range-List Partitioning
Phân theo tháng, subpartition theo vùng:

CREATE TABLE transactions (
  trans_id     NUMBER,
  trans_date   DATE,
  region       VARCHAR2(10)
)
PARTITION BY RANGE (trans_date)
SUBPARTITION BY LIST (region)
(
  PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01','YYYY-MM-DD'))
  (
    SUBPARTITION asia VALUES ('VN', 'TH', 'ID'),
    SUBPARTITION europe VALUES ('FR', 'DE', 'UK')
  ),
  PARTITION p2024 VALUES LESS THAN (MAXVALUE)
  (
    SUBPARTITION asia VALUES ('JP', 'KR'),
    SUBPARTITION europe VALUES ('IT', 'ES')
  )
);
Ví dụ 3: Interval-List Partitioning (Oracle 11g+)
Tự động mở rộng partition theo tháng + chia sub theo tỉnh:

CREATE TABLE logs (
  log_id     NUMBER,
  log_date   DATE,
  province   VARCHAR2(10)
)
PARTITION BY RANGE (log_date)
INTERVAL (NUMTODSINTERVAL(1, 'MONTH'))
SUBPARTITION BY LIST (province)
SUBPARTITION TEMPLATE
(
  SUBPARTITION north VALUES ('HN', 'HP'),
  SUBPARTITION south VALUES ('HCM', 'CT')
)
(
  PARTITION p_start VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD'))
);

- Interval Partitioning: Là một biến thể nâng cao của Range Partitioning, được Oracle giới thiệu từ Oracle 11g trở đi.
   + Khi chèn dữ liệu vượt ngoài các range partition đã khai báo, Oracle sẽ tự động tạo partition mới với khoảng cách cố định (INTERVAL).
   + Thích hợp cho dữ liệu phát sinh liên tục theo thời gian như: Logs, giao dịch, đo lường thiết bị, sự kiện hệ thống...
Cấu trúc cơ bản:

CREATE TABLE sales (
  sale_id     NUMBER,
  sale_date   DATE,
  amount      NUMBER
)
PARTITION BY RANGE (sale_date)
INTERVAL (NUMTODSINTERVAL(1, 'MONTH'))
(
  PARTITION p202401 VALUES LESS THAN (TO_DATE('2024-02-01', 'YYYY-MM-DD'))
);

Sau khi tạo bảng trên, nếu insert dữ liệu tháng 03/2024, Oracle sẽ tự động tạo partition cho 03/2024.

Cú pháp INTERVAL chi tiết:
Mức INTERVAL Cú pháp SQL
1 ngày NUMTODSINTERVAL(1, 'DAY')
1 tháng NUMTODSINTERVAL(1, 'MONTH')
1 giờ NUMTODSINTERVAL(1, 'HOUR')
7 ngày (tuần) NUMTODSINTERVAL(7, 'DAY')

- Reference Partitioning: Là một loại phân vùng được giới thiệu từ Oracle 11g, cho phép bảng con (child table) kế thừa phân vùng từ bảng cha (parent table) thông qua khóa ngoại (FOREIGN KEY).

- System Partitioning: Là hình thức phân vùng đặc biệt, cho phép hoàn toàn kiểm soát việc đưa dữ liệu vào partition nào, Oracle không can thiệp bất kỳ logic nào dựa trên cột hay giá trị.
Cú pháp cơ bản:

CREATE TABLE logs (
  id         NUMBER,
  log_type   VARCHAR2(10),
  log_data   CLOB
)
PARTITION BY SYSTEM
(
  PARTITION p_errors,
  PARTITION p_info,
  PARTITION p_debug
);
Lưu ý:
+ Không có cột nào được khai báo để phân vùng.
+ Oracle không xác định phân vùng khi insert.
+ Bắt buộc phải chỉ rõ partition khi thêm dữ liệu:
    INSERT INTO logs PARTITION (p_info) VALUES (1, 'INFO', 'Log content');
    INSERT INTO logs PARTITION (p_errors) VALUES (2, 'ERROR', 'Error details');
+ Một số tình huống điển hình sử dụng System Partitioning:
   + Ghi log từ nhiều hệ thống độc lập:
       Từng hệ thống INSERT ... PARTITION (...) vào đúng phần riêng.
            PARTITION p_app_logs
            PARTITION p_sys_logs
            PARTITION p_user_logs
   + Phân phối dữ liệu song song theo worker hoặc tiến trình: 
        Ví dụ có 8 worker song song → tạo 8 partition: PARTITION p0, p1, ..., p7. Mỗi tiến trình dùng INSERT INTO logs PARTITION (pN) ...
   + Custom routing theo thuật toán hash:
        Dùng logic ứng dụng để tính: partition_id := MOD(customer_id, 4). Rồi insert vào p0 đến p3.