Oracle 5 — Partitioning & lưu trữ
Oracle 5 — Partitioning & lưu trữ
Có một khoảnh khắc trong đời mọi cơ sở dữ liệu doanh nghiệp: bảng giao dịch chạm mốc hàng tỷ dòng, mỗi lần quét mất vài phút, và cái ngày cuối tháng bạn cần xoá dữ liệu 7 năm trước theo quy định lưu trữ thì một câu DELETE chạy suốt đêm chưa xong. Đây chính là địa hạt mà partitioning của Oracle được sinh ra để giải quyết: chia một bảng logic khổng lồ thành nhiều phân vùng vật lý nhỏ, để optimizer chỉ đụng vào phần cần thiết và để việc bảo trì (nạp lô, xoá dữ liệu cũ) trở thành thao tác metadata gần như tức thì thay vì hàng giờ I/O.
Bài này đi sâu vào ba lớp gắn bó với nhau: partitioning (cách chia bảng), cấu trúc lưu trữ vật lý (tablespace → segment → extent → block), và ASM (lớp quản lý đĩa). Chúng ta cũng bàn IOT, nén dữ liệu và nối lại với cách PostgreSQL làm điều tương tự.
Lưu ý sandbox: Toàn bộ DDL trong bài là cú pháp Oracle. Sandbox của Knowledge Base chạy PostgreSQL, nên các lệnh Oracle bên dưới đều ghi (minh hoạ — Oracle, không chạy trong sandbox Postgres). Đừng dán vào psql — cú pháp
PARTITION BY RANGE (...) (PARTITION ...),EXCHANGE PARTITION,SEGMENT,TABLESPACE ... DATAFILElà đặc thù Oracle.
1. Partitioning là gì và tại sao
Một bảng partitioned trong Oracle về mặt logic vẫn là một bảng — ứng dụng SELECT * FROM sales WHERE ... mà không cần biết nó bị chia. Nhưng về mặt vật lý, dữ liệu được phân bổ vào nhiều partition, mỗi partition là một segment độc lập, có thể nằm ở tablespace khác nhau, nén khác nhau, thậm chí trên đĩa khác nhau.
Ba lợi ích chi phối mọi quyết định partitioning:
- Hiệu năng truy vấn — nhờ partition pruning, optimizer bỏ qua các partition không liên quan.
- Khả năng bảo trì — thêm/xoá/hoán đổi partition là thao tác metadata, không phải quét dữ liệu.
- Khả dụng — lỗi hoặc bảo trì trên một partition không khoá toàn bảng; có thể rebuild index từng phần.
Bốn kiểu phân vùng cơ bản
RANGE — chia theo khoảng giá trị, thường theo thời gian. Đây là kiểu phổ biến nhất vì dữ liệu doanh nghiệp gần như luôn có trục thời gian (ngày giao dịch, ngày tạo).
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
CREATE TABLE sales (
sale_id NUMBER,
sale_date DATE NOT NULL,
customer_id NUMBER,
amount NUMBER(12,2)
)
PARTITION BY RANGE (sale_date) (
PARTITION p_2024_q1 VALUES LESS THAN (DATE '2024-04-01'),
PARTITION p_2024_q2 VALUES LESS THAN (DATE '2024-07-01'),
PARTITION p_2024_q3 VALUES LESS THAN (DATE '2024-10-01'),
PARTITION p_2024_q4 VALUES LESS THAN (DATE '2025-01-01'),
PARTITION p_max VALUES LESS THAN (MAXVALUE)
);
Ranh giới là VALUES LESS THAN — một dòng có sale_date = 2024-05-10 rơi vào p_2024_q2. Partition p_max là "cái phễu" hứng mọi giá trị vượt biên; có nó thì INSERT không bao giờ lỗi ORA-14400 (không có partition khớp), nhưng cũng dễ khiến dữ liệu mới dồn hết vào một partition khổng lồ nếu quên tách ra.
LIST — chia theo tập giá trị rời rạc, ví dụ theo vùng miền, mã trạng thái.
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
CREATE TABLE customers (
id NUMBER,
region VARCHAR2(10),
name VARCHAR2(200)
)
PARTITION BY LIST (region) (
PARTITION p_north VALUES ('HN', 'HP', 'QN'),
PARTITION p_south VALUES ('HCM', 'CT', 'BD'),
PARTITION p_other VALUES (DEFAULT)
);
DEFAULT là phễu hứng cho LIST, tương đương MAXVALUE của RANGE.
HASH — Oracle băm khoá phân vùng để rải đều dữ liệu vào N partition. Dùng khi không có trục tự nhiên để chia nhưng muốn phân tán I/O và cho phép partition-wise join. Số partition nên là luỹ thừa của 2 để hàm băm rải đều.
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
CREATE TABLE orders (
order_id NUMBER,
customer_id NUMBER,
total NUMBER(12,2)
)
PARTITION BY HASH (customer_id)
PARTITIONS 8;
COMPOSITE — chia hai tầng: partition trước rồi subpartition trong mỗi partition. Phổ biến nhất là RANGE-HASH (range theo thời gian, hash theo khách hàng để rải I/O trong từng tháng) và RANGE-LIST (range theo thời gian, list theo vùng).
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
CREATE TABLE sales_c (
sale_id NUMBER,
sale_date DATE,
region VARCHAR2(10),
amount NUMBER(12,2)
)
PARTITION BY RANGE (sale_date)
SUBPARTITION BY LIST (region)
SUBPARTITION TEMPLATE (
SUBPARTITION sp_north VALUES ('HN','HP'),
SUBPARTITION sp_south VALUES ('HCM','CT'),
SUBPARTITION sp_other VALUES (DEFAULT)
)
( PARTITION p_2024 VALUES LESS THAN (DATE '2025-01-01'),
PARTITION p_2025 VALUES LESS THAN (DATE '2026-01-01') );
Interval partitioning — hết cảnh quên tạo partition
Với RANGE thuần, mỗi khi sang tháng/quý mới bạn phải nhớ ADD PARTITION; quên là INSERT rơi vào p_max hoặc lỗi. Interval partitioning giao việc đó cho Oracle: khi có dòng vượt biên partition cuối, Oracle tự tạo partition mới theo bước khai báo.
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
CREATE TABLE events (
id NUMBER,
created_at DATE
)
PARTITION BY RANGE (created_at)
INTERVAL (NUMTOYMINTERVAL(1, 'MONTH')) -- mỗi partition = 1 tháng
( PARTITION p_seed VALUES LESS THAN (DATE '2024-01-01') );
Phải có ít nhất một partition "seed" cố định làm mốc; từ đó trở đi partition mới sinh tự động, tên hệ thống (SYS_Pxxxx).
Reference partitioning giải quyết bài toán bảng con: bảng order_items không có cột ngày, nhưng muốn nó chia theo cùng partition với bảng cha orders qua khoá ngoại. Khai báo PARTITION BY REFERENCE (fk_constraint) để Oracle kế thừa sơ đồ partition từ bảng cha — bảo trì cha thì con đi theo.
2. Partition pruning & partition-wise join
Partition pruning là lý do chính khiến partitioning tăng tốc truy vấn: khi mệnh đề WHERE chứa khoá phân vùng, optimizer loại bỏ các partition không thể chứa kết quả và chỉ quét phần còn lại.
Có hai dạng:
- Static pruning — điều kiện là hằng số biết lúc phân tích (
sale_date >= DATE '2024-07-01'); optimizer chốt partition ngay khi tạo plan. TrongEXPLAIN PLANthấyPARTITION RANGE SINGLE/ITERATORvớiPstart/Pstopcụ thể. - Dynamic pruning — điều kiện phụ thuộc bind variable hoặc kết quả subquery, chỉ biết lúc chạy; plan hiện
Pstart = KEY.
Điều kiện tiên quyết: WHERE phải chạm khoá phân vùng. Nếu lọc sale_date bằng một hàm che khoá (ví dụ TO_CHAR(sale_date,'YYYY') = '2024') thì pruning hỏng — Oracle không thể suy ra partition từ biểu thức đã biến đổi. Luôn viết điều kiện trực tiếp trên cột phân vùng. (Đây cũng là bài học về SARGable đã bàn ở Tối ưu & tuning.)
Partition-wise join — khi hai bảng cùng partition theo cùng khoá (ví dụ cả orders và order_items đều HASH theo customer_id với cùng số partition), Oracle join từng cặp partition tương ứng thay vì join toàn bộ. Điều này giảm mạnh dung lượng phải hash/sort và cực kỳ quan trọng khi chạy song song (parallel query) trên RAC.
Local index vs global index
Index trên bảng partitioned có hai loại, và chọn sai là một trong những lỗi thiết kế tốn kém nhất:
- LOCAL index — mỗi partition dữ liệu có một partition index riêng, khoá cùng biên. Đây là mặc định nên có: khi
DROP/TRUNCATE/EXCHANGEmột partition, index local của nó theo cùng, không làm hỏng index các partition khác. Bảo trì cực rẻ. - GLOBAL index — một cây B-tree (hoặc global partitioned) trải trên toàn bảng, độc lập với biên partition dữ liệu. Cần khi truy vấn lọc theo cột không phải khoá phân vùng và cần unique toàn bảng. Nhược điểm: thao tác partition dữ liệu làm index này
UNUSABLE, phảiUPDATE INDEXES(rebuild online) hoặc rebuild lại — đắt.
Quy tắc: ưu tiên local index. Chỉ dùng global khi thực sự cần unique/tra cứu xuyên partition, và khi đó luôn kèm UPDATE INDEXES trong lệnh bảo trì để tránh index rơi vào trạng thái UNUSABLE.
3. Bảo trì partition — nơi partitioning tỏa sáng
Đây là phần mang lại giá trị vận hành lớn nhất. Tất cả đều là thao tác metadata hoặc chuyển đổi con trỏ, nhanh hơn nhiều lần so với INSERT/DELETE dòng-theo-dòng.
- ADD PARTITION — thêm partition cho khoảng dữ liệu tương lai (không cần nếu đã dùng interval).
- DROP PARTITION — xoá cả partition (dữ liệu + segment) tức thì. Đây là cách xoá dữ liệu cũ theo vòng đời: thay vì
DELETE FROM sales WHERE sale_date < ...chạy hàng giờ và sinh undo/redo khổng lồ, chỉ cầnALTER TABLE sales DROP PARTITION p_2018_q1. - TRUNCATE PARTITION — dọn sạch dữ liệu một partition nhưng giữ cấu trúc, gần như tức thì.
- EXCHANGE PARTITION — hoán đổi con trỏ segment giữa một partition và một bảng thường (staging) có cùng cấu trúc. Đây là kỹ thuật nạp lô nhanh nhất.
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
-- Nạp dữ liệu tháng mới vào bảng staging (thoải mái index, validate, nén)
CREATE TABLE sales_stage AS SELECT * FROM sales WHERE 1=0;
-- ... INSERT /*+ APPEND */ hàng chục triệu dòng vào sales_stage ...
-- Hoán đổi: staging trở thành partition, chỉ đổi metadata (mili giây)
ALTER TABLE sales
EXCHANGE PARTITION p_2025_01
WITH TABLE sales_stage
INCLUDING INDEXES
WITHOUT VALIDATION;
EXCHANGE PARTITION không sao chép dữ liệu — nó tráo con trỏ: dữ liệu vốn nằm trong sales_stage giờ "thuộc về" partition p_2025_01, và partition cũ (nếu có) chuyển ngược sang bảng stage. WITHOUT VALIDATION bỏ qua bước kiểm tra mọi dòng có thực sự nằm trong biên partition — cực nhanh nhưng chỉ dùng khi bạn chắc chắn dữ liệu staging đúng khoảng, nếu không sẽ có dòng "lạc chỗ" gây kết quả sai khi pruning.
Online operations — từ 12c/19c, nhiều thao tác chạy được với ONLINE không khoá DML: ALTER TABLE ... MOVE PARTITION ... ONLINE, MODIFY PARTITION ... COMPRESS, và move/split partition online. Điều này cho phép nén hoặc di dời partition cũ sang tablespace lưu trữ giá rẻ mà không ngừng ứng dụng.
4. Index-Organized Table (IOT) & cluster
Bảng heap thông thường của Oracle lưu dữ liệu vô trật tự, còn primary key nằm ở một B-tree index riêng trỏ tới rowid. Index-Organized Table gộp cả hai: dữ liệu nằm ngay trong lá của B-tree khoá chính, sắp xếp theo PK. Không có heap riêng, không có index PK riêng.
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
CREATE TABLE lookup_iot (
code VARCHAR2(20),
label VARCHAR2(200),
CONSTRAINT pk_lookup PRIMARY KEY (code)
)
ORGANIZATION INDEX;
Khi nào dùng IOT: bảng truy cập chủ yếu qua PK, dòng nhỏ, tra cứu điểm/theo range trên PK (bảng tra cứu, bảng liên kết many-to-many, dữ liệu chuỗi thời gian truy vấn theo khoá). Lợi: tiết kiệm dung lượng (không lặp PK hai nơi) và một lần truy cập B-tree đã lấy được cả dữ liệu (không cần bước "table access by rowid"). Hạn: cột không-PK lớn thường cần khai báo OVERFLOW để tràn sang segment phụ; index phụ trên IOT dùng logical rowid nên có thể chậm hơn.
Cluster là cơ chế cũ hơn: lưu các dòng của nhiều bảng có cùng khoá cluster cạnh nhau trong cùng block (ví dụ orders và order_items cùng order_id), để join chúng chỉ tốn một lần đọc block. Ít dùng ngày nay vì kém linh hoạt, nhưng vẫn hiệu quả cho các cặp bảng luôn join theo cùng khoá và ít thay đổi.
5. Compression — nén để chứa nhiều hơn, đọc ít hơn
Nén không chỉ tiết kiệm đĩa mà còn giảm I/O: block nén chứa nhiều dòng hơn nên đọc cùng lượng dữ liệu tốn ít block hơn. Oracle có nhiều mức:
- Basic compression (
COMPRESS/ROW STORE COMPRESS BASIC) — nén khi nạp lô bằng direct-path (INSERT /*+ APPEND */, CTAS,EXCHANGE). DML thường (INSERT lẻ) không được nén. Phù hợp bảng chỉ-đọc hoặc partition cũ. - Advanced row compression (
ROW STORE COMPRESS ADVANCED, cần tùy chọn Advanced Compression) — nén cả với DML thông thường; Oracle nén theo lô trong block khi block gần đầy, giữ được lợi ích nén trên bảng OLTP đang ghi. - HCC — Hybrid Columnar Compression — nén theo cột trong "compression unit", đạt tỉ lệ rất cao (thường gấp nhiều lần row compression) cho kho dữ liệu. HCC chỉ chạy trên storage của Oracle: Exadata, ZFS Storage Appliance, và Pillar/FS1 — không có trên đĩa thường. Có các mức
QUERY LOW/HIGH(ưu tiên tốc độ đọc) vàARCHIVE LOW/HIGH(ưu tiên tỉ lệ nén tối đa, cho dữ liệu ít truy cập).
Chiến lược thực dụng: partition nóng (tháng hiện tại, đang ghi) để không nén hoặc advanced; partition nguội (dữ liệu cũ) MOVE ... COMPRESS sang HCC/basic và chuyển sang tablespace read-only giá rẻ. Đây gọi là Information Lifecycle Management (ILM), và Oracle có ADO (Automatic Data Optimization) với ILM ADD POLICY để tự động hoá theo "heat map".
6. ASM — Automatic Storage Management
Bên dưới tablespace là đĩa vật lý, và quản lý đĩa cho database quy mô lớn (nhất là RAC nhiều node dùng chung storage) là bài toán riêng. ASM là một volume manager + file system chuyên cho Oracle, chạy như một instance nhẹ riêng (+ASM).
Khái niệm cốt lõi:
- Disk group — tập hợp các đĩa (LUN) mà ASM gộp lại thành một vùng lưu trữ logic. Datafile, redo log, control file... đều nằm trong disk group thay vì trên file system OS.
- Striping — ASM tự rải dữ liệu đều trên tất cả đĩa trong disk group, cân bằng I/O mà không cần DBA thủ công phân bổ file vào đĩa nào.
- Mirroring / redundancy — mức dự phòng khai báo ở cấp disk group:
EXTERNAL(không mirror, tin vào SAN bên dưới),NORMAL(2 bản sao),HIGH(3 bản sao). ASM đặt các bản sao vào failure group khác nhau để một tủ đĩa/controller hỏng không mất dữ liệu. - Rebalance — khi thêm/bớt đĩa, ASM tự động di chuyển extent để rải lại đều, chạy online không ngừng database.
Với DBA, ASM có nghĩa là: không còn quản lý filesystem, không phân mảnh thủ công, thêm dung lượng chỉ là ALTER DISKGROUP ... ADD DISK rồi ASM tự rebalance. Đây là nền tảng lưu trữ tiêu chuẩn cho các cụm RAC — sẽ bàn kỹ ở RAC & Data Guard.
7. Cấu trúc lưu trữ logic: tablespace → segment → extent → block
Để hiểu partitioning và nén thực sự làm gì với đĩa, cần nắm phân cấp lưu trữ logic của Oracle (từ lớn tới nhỏ):
TABLESPACE (vd: SALES_DATA — gồm ≥1 datafile trên đĩa/ASM)
└─ SEGMENT (= 1 partition / bảng / index; bảng partitioned = nhiều segment)
└─ EXTENT (= dãy block liền kề, cấp phát một lần)
└─ DATA BLOCK (đơn vị I/O nhỏ nhất, mặc định 8KB;
PCTFREE chừa chỗ cho UPDATE)
↑ High Water Mark = block cao nhất từng dùng của segment;
full scan quét tới đây, kể cả block đã DELETE để trống.
- Tablespace — đơn vị lưu trữ logic cấp cao, ánh xạ tới một hoặc nhiều datafile trên đĩa (hoặc trên ASM). Mỗi partition có thể đặt vào tablespace riêng — đây là cách tách dữ liệu nóng/nguội lên storage khác nhau.
- Segment — mọi đối tượng chiếm chỗ là một segment: một bảng heap là một segment, nhưng một bảng partitioned là nhiều segment (mỗi partition một cái). Index, LOB cũng là segment riêng.
- Extent — một dãy block liền kề cấp phát một lần cho segment. Segment lớn dần bằng cách xin thêm extent.
- Data block — đơn vị I/O nhỏ nhất Oracle đọc/ghi, mặc định 8KB. Mọi thao tác đọc đĩa đều theo block.
Ba khái niệm vận hành cần nhớ:
PCTFREE — phần trăm không gian mỗi block chừa lại cho việc UPDATE làm dòng dài ra sau này. PCTFREE 10 (mặc định) giữ 10% trống. Bảng chỉ-INSERT (append-only, như bảng log/giao dịch) nên đặt PCTFREE 0 hoặc thấp để nhồi đầy block, tiết kiệm chỗ và giảm I/O. Bảng UPDATE nhiều nên để cao hơn để tránh row migration/chaining (dòng lớn ra không vừa block, phải dời chỗ, gây đọc thêm block).
High Water Mark (HWM) — ranh giới đánh dấu block cao nhất từng được dùng của segment. Full table scan quét từ đầu tới HWM, kể cả block đã bị DELETE để trống. Đó là lý do sau khi DELETE hàng loạt, bảng vẫn quét chậm — HWM chưa lùi lại. Chỉ TRUNCATE, MOVE, hoặc shrink mới hạ HWM. (Đây là lập luận nữa cho việc dùng DROP/TRUNCATE PARTITION thay vì DELETE để dọn dữ liệu cũ.)
TEMP và UNDO — hai tablespace đặc biệt: TEMP chứa dữ liệu tạm cho sort/hash/global temporary table khi vượt bộ nhớ PGA; UNDO chứa ảnh cũ (before-image) của dữ liệu để rollback, đảm bảo read consistency (MVCC của Oracle) và cấp cho flashback. Câu truy vấn lớn nuốt nhiều TEMP; transaction dài giữ UNDO lâu và có thể gây lỗi ORA-01555 snapshot too old nếu UNDO bị ghi đè trước khi truy vấn dài đọc xong.
8. Use case thực tế
Bảng giao dịch theo tháng, xoá dữ liệu cũ theo vòng đời
Bảng transactions hàng tỷ dòng, quy định giữ 13 tháng gần nhất. Thiết kế: RANGE partition theo txn_date, một partition mỗi tháng, dùng interval để Oracle tự tạo partition tháng mới, local index cho mọi index.
Hàng tháng, một job dọn dẹp chỉ cần:
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
ALTER TABLE transactions DROP PARTITION txn_2024_05 UPDATE INDEXES;
Xoá 80 triệu dòng của tháng 5/2024 trong vài giây (thao tác segment), thay vì DELETE chạy nhiều giờ, sinh gigabyte undo/redo, khoá bảng và để lại HWM cao. UPDATE INDEXES giữ mọi global index (nếu có) hợp lệ; với local index thì không cần vì chúng bị xoá theo partition.
Nạp lô hàng đêm bằng exchange partition
Kho dữ liệu nạp một tháng dữ liệu mới mỗi đêm. Nếu INSERT trực tiếp vào bảng đích partitioned, ta phải chịu index maintenance và khoá ở bảng đang phục vụ báo cáo. Thay vào đó:
- Nạp vào bảng staging
txn_stagegiống hệt cấu trúc một partition (direct-pathINSERT /*+ APPEND */, tự do build index, nén, validate offline). - Hoán đổi vào partition bằng một lệnh metadata:
-- (minh hoạ — Oracle, không chạy trong sandbox Postgres)
ALTER TABLE transactions
EXCHANGE PARTITION txn_2025_06
WITH TABLE txn_stage
INCLUDING INDEXES
WITHOUT VALIDATION
UPDATE GLOBAL INDEXES;
Bảng đích chỉ "đổi con trỏ" trong mili giây — người dùng báo cáo gần như không thấy gián đoạn. Toàn bộ công việc nặng (nạp, index, nén) đã làm xong ngoài bảng production. Đây là mẫu ETL kinh điển của Oracle DW.
9. So với PostgreSQL
PostgreSQL từ v10 có declarative partitioning (PARTITION BY RANGE/LIST/HASH, CREATE TABLE ... PARTITION OF), khái niệm rất giống Oracle: partition pruning, attach/detach partition (tương đương exchange). Khác biệt đáng chú ý:
| Oracle | PostgreSQL | |
|---|---|---|
| Tự tạo partition | Interval partitioning (native) | Không có sẵn — cần pg_partman/cron |
| Nạp lô nhanh | EXCHANGE PARTITION | ATTACH PARTITION (tương đương) |
| Composite | RANGE-HASH/RANGE-LIST 2 tầng | Sub-partition qua partition lồng nhau |
| Local index | Native, khoá theo partition | Index tạo trên partitioned table tự lan xuống (v11+) |
| Nén cột | HCC (chỉ Exadata/storage Oracle) | Không native (cần column store ngoài) |
| Sharding | RAC/Sharding option | Citus, Postgres FDW |
Nếu bạn đến từ thế giới PostgreSQL, xem Phân vùng, sharding & mở rộng quy mô để đối chiếu chi tiết cách Postgres partition, prune và scale-out.
Ghi nhớ
- RANGE theo thời gian là kiểu partition phổ biến nhất; kèm interval để hết cảnh quên tạo partition mới. LIST cho giá trị rời rạc, HASH để rải I/O, COMPOSITE khi cần hai trục.
- Partition pruning chỉ chạy khi
WHEREchạm trực tiếp khoá phân vùng — đừng bọc khoá trong hàm. - Ưu tiên LOCAL index; chỉ dùng GLOBAL khi cần tra cứu/unique xuyên partition, và luôn kèm
UPDATE INDEXESkhi bảo trì. - Dọn dữ liệu cũ bằng
DROP/TRUNCATE PARTITION, nạp lô bằngEXCHANGE PARTITION— đều là thao tác metadata, nhanh hơn DELETE/INSERT nhiều lần và không để HWM cao. - IOT cho bảng truy cập chủ yếu qua PK; compression (basic/advanced/HCC) để giảm cả đĩa lẫn I/O, kết hợp ILM cho partition nguội. HCC chỉ trên storage Oracle.
- ASM = volume manager của Oracle: disk group, striping tự động, redundancy theo failure group, rebalance online — nền tảng cho RAC.
- Nắm phân cấp tablespace → segment → extent → block; hiểu PCTFREE (chỗ chừa cho UPDATE), HWM (vì sao DELETE không làm bảng nhanh lại), và vai trò của TEMP/UNDO.
Bài liên quan: Tối ưu & tuning Oracle · RAC & Data Guard — độ sẵn sàng cao · PostgreSQL: phân vùng, sharding & mở rộng
Bài viết liên quan
Cách index hoạt động (B-Tree), đọc EXPLAIN, seq scan vs index scan và mẫu tối ưu truy vấn.
Khoá, ràng buộc, quan hệ và chuẩn hoá 1NF/2NF/3NF — thiết kế lược đồ đúng từ đầu.
Kết nhiều bảng đúng cách: các loại JOIN, bẫy thường gặp và phép hợp tập.
Truy vấn lồng, CTE (WITH), CTE đệ quy và hàm cửa sổ — vũ khí cho phân tích nâng cao.