05/02/2025
Index Trong Oracle
Index (Chỉ mục) trong Oracle giúp cải thiện hiệu suất truy vấn bằng cách tăng tốc độ tìm kiếm dữ liệu trong bảng. Khi bạn thực hiện câu lệnh SELECT với điều kiện WHERE, Oracle sẽ sử dụng index để nhanh chóng truy xuất dữ liệu thay vì quét toàn bộ bảng (Full Table Scan).
________________________________________
1. Các Loại Index Trong Oracle
Oracle hỗ trợ nhiều loại index, mỗi loại phù hợp với từng tình huống cụ thể.
Loại Index Mô Tả
B-Tree Index Loại index mặc định, hoạt động tốt cho truy vấn tìm kiếm và lọc dữ liệu.
Bitmap Index Hiệu quả khi dữ liệu có số lượng giá trị khác nhau ít (low cardinality), ví dụ: Giới tính, trạng thái (Active/Inactive).
Unique Index Đảm bảo các giá trị trong cột là duy nhất, thường được tạo tự động khi sử dụng PRIMARY KEY hoặc UNIQUE KEY.
Function-Based Index (FBI) Tạo index trên kết quả của một hàm hoặc biểu thức (ví dụ: UPPER(column_name)).
Reverse Key Index Đảo ngược giá trị khóa trước khi lưu vào index, hữu ích để tránh tranh chấp trong môi trường nhiều người dùng (RAC).
Compressed Index Dùng để giảm kích thước index khi có dữ liệu lặp lại nhiều.
Invisible Index Index tồn tại nhưng không được Oracle sử dụng trừ khi được chỉ định trong truy vấn.
Partitioned Index Index được chia thành các phần nhỏ để tăng hiệu suất trên các bảng có lượng dữ liệu lớn.
Domain Index Dùng cho dữ liệu đặc biệt như văn bản, hình ảnh (Oracle Text, Spatial).
________________________________________
2. Cách Tạo Index
2.1. Tạo B-Tree Index (Mặc Định)
CREATE INDEX emp_name_idx ON employees(last_name);
• emp_name_idx: Tên của index.
• employees: Tên bảng.
• last_name: Cột được lập index.
📌 Lợi ích: Tăng tốc độ tìm kiếm trên cột last_name khi thực hiện truy vấn WHERE last_name = 'Smith'.
________________________________________
2.2. Tạo Unique Index
Oracle tự động tạo Unique Index khi sử dụng PRIMARY KEY hoặc UNIQUE KEY. Nhưng bạn cũng có thể tạo thủ công:
CREATE UNIQUE INDEX emp_email_idx ON employees(email);
📌 Lợi ích: Đảm bảo mỗi giá trị trong email là duy nhất.
________________________________________
2.3. Tạo Bitmap Index
CREATE BITMAP INDEX emp_status_idx ON employees(status);
📌 Sử dụng khi:
• Cột có ít giá trị duy nhất (low cardinality), ví dụ: status có các giá trị {Active, Inactive, Pending}.
• Dữ liệu có nhiều truy vấn phân tích (OLAP, Data Warehouse).
________________________________________
2.4. Tạo Function-Based Index (FBI)
CREATE INDEX emp_upper_name_idx ON employees(UPPER(last_name));
📌 Sử dụng khi:
• Bạn thường xuyên tìm kiếm dữ liệu đã qua biến đổi:
SELECT * FROM employees WHERE UPPER(last_name) = 'SMITH';
• Không cần sử dụng Function-Based Index nếu truy vấn dùng last_name = 'SMITH' mà không có UPPER().
________________________________________
2.5. Tạo Reverse Key Index
CREATE INDEX emp_phone_idx ON employees(phone_number) REVERSE;
📌 Sử dụng khi:
• Giá trị index tăng dần (ví dụ: ID SEQUENCE), giúp tránh tranh chấp ghi khi nhiều session chèn dữ liệu đồng thời.
• Thích hợp cho Oracle RAC.
________________________________________
2.6. Tạo Partitioned Index
CREATE INDEX emp_dept_idx ON employees(department_id) LOCAL;
📌 Sử dụng khi:
• Bảng đã được partitioned (chia thành các phần nhỏ theo department_id).
• Tránh quét toàn bộ index.
________________________________________
2.7. Tạo Invisible Index
CREATE INDEX emp_salary_idx ON employees(salary) INVISIBLE;
📌 Sử dụng khi:
• Bạn muốn kiểm tra hiệu suất index mà không ảnh hưởng đến truy vấn thông thường.
• Bật index tạm thời khi cần:
ALTER INDEX emp_salary_idx VISIBLE;
________________________________________
3. Kiểm Tra Index
3.1. Liệt Kê Các Index Trên Một Bảng
SELECT INDEX_NAME, INDEX_TYPE, UNIQUENESS FROM DBA_INDEXES WHERE TABLE_NAME = 'EMPLOYEES';
3.2. Kiểm Tra Index Đang Được Sử Dụng Hay Không
SELECT * FROM V$SQL_PLAN WHERE OBJECT_TYPE = 'INDEX';
• Nếu OBJECT_TYPE = INDEX FULL SCAN, Oracle đang sử dụng Full Index Scan.
• Nếu OBJECT_TYPE = INDEX RANGE SCAN, Oracle đang sử dụng Index Range Scan.
3.3. Xem Chi Tiết Cấu Trúc Index
SELECT * FROM DBA_IND_COLUMNS WHERE INDEX_NAME = 'EMP_NAME_IDX';
________________________________________
4. Khi Nào Cần Dùng Index?
Dùng Index khi: ✅ Cột thường xuyên xuất hiện trong điều kiện WHERE, JOIN, ORDER BY.
✅ Dữ liệu lớn, truy vấn mất nhiều thời gian.
✅ Giá trị trong cột có độ phân biệt cao (high cardinality).
✅ Các truy vấn lọc một phần nhỏ dữ liệu (dưới 10% số hàng).
Không nên dùng Index khi: ❌ Bảng quá nhỏ (Oracle sẽ full table scan nhanh hơn).
❌ Cột có ít giá trị khác nhau (low cardinality, ngoại trừ Bitmap Index).
❌ Câu lệnh thường xuyên cập nhật (UPDATE, DELETE, INSERT), vì index làm giảm tốc độ ghi dữ liệu.
________________________________________
5. Xóa, Vô Hiệu Hóa, và Tái Xây Dựng Index
5.1. Xóa Index
DROP INDEX emp_name_idx;
5.2. Vô Hiệu Hóa Index
ALTER INDEX emp_name_idx UNUSABLE;
🔹 Index vẫn tồn tại, nhưng Oracle không sử dụng nó.
5.3. Tái Xây Dựng Index
ALTER INDEX emp_name_idx REBUILD;
🔹 Dùng khi:
• Index bị mất hiệu suất do nhiều thay đổi dữ liệu.
• Giảm phân mảnh index.
________________________________________
6. Kiểm Tra Index Có Hoạt Động Không?
🔹 Kiểm tra truy vấn có sử dụng Index không:
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE last_name = 'Smith';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
🔹 Nếu có INDEX RANGE SCAN hoặc INDEX UNIQUE SCAN, thì index đang được sử dụng.
________________________________________
🎯 Kết Luận
🔹 Index giúp cải thiện hiệu suất truy vấn, nhưng không phải lúc nào cũng có lợi.
🔹 Chọn loại Index phù hợp dựa trên cấu trúc dữ liệu và kiểu truy vấn.
🔹 B-Tree Index là loại thông dụng nhất, Bitmap Index phù hợp với low-cardinality, Function-Based Index giúp tối ưu hóa truy vấn có hàm.
🔹 Kiểm tra hiệu suất Index thường xuyên để đảm bảo không bị phân mảnh và đang thực sự được sử dụng.
🚀 Áp dụng ngay các kiến thức trên để tối ưu hóa hiệu suất database của bạn! 🚀