Index
Nội dung bài · 5 mục
- 1.Khái niệm
- 2.Ví dụ
- 3.Thử ngay
- 4.Lỗi hay gặp
- 5.Tóm tắt
Bảng đơn hàng có vài triệu dòng. Câu truy vấn tìm đơn của một khách mất 5 giây, vì
Oracle phải đọc từng dòng để so customer_id. Index giúp Oracle đi thẳng tới
đúng những dòng cần tìm.
Khái niệm
🐢 Full table scan: cách Oracle đọc lần lượt mọi dòng của bảng để tìm dòng thoả điều kiện.
📇 Index: bản sắp xếp sẵn giá trị của cột kèm vị trí dòng, giúp tìm theo cột đó mà không đọc cả bảng.
Ví dụ
CREATE INDEX idx_demo
ON order_lines (product_id);- Từ đây, câu
WHERE product_id = 1trênorder_linesdùng được index thay vì đọc cả bảng. - Oracle tự tạo index cho khoá chính và cột
UNIQUE. - Khoá ngoại không tự có index. Cột khoá ngoại hay dùng để
JOINnên thường cần tạo index. - Index có giá: tốn thêm dung lượng, và mỗi lần
INSERT,UPDATE,DELETEOracle phải cập nhật cả index.
Thử ngay
Tạo index rồi xem bảng orders có index trên những cột nào:
CREATE INDEX idx_orders_customer
ON orders (customer_id);
SELECT column_name
FROM user_ind_columns
WHERE table_name = 'ORDERS'
ORDER BY column_name;user_ind_columns là view hệ thống của Oracle, liệt kê cột của các index
thuộc user đang đăng nhập.
Đoán trước khi chạy: bạn chỉ tạo một index. Kết quả có mấy dòng?
Xem kết quả
| COLUMN_NAME |
|---|
| CUSTOMER_ID |
| ORDER_ID |
Hai dòng. CUSTOMER_ID là index vừa tạo. ORDER_ID là index Oracle tự tạo
cho khoá chính từ lúc tạo bảng.
Lỗi hay gặp
Bọc hàm quanh cột trong WHERE. Index lưu giá trị gốc của
order_date, không lưu kết quả của TRUNC(order_date) (cắt phần giờ), nên Oracle không
dùng được index và phải đọc cả bảng.
-- SAI — hàm quanh cột làm mất tác dụng của index
SELECT order_id FROM orders
WHERE TRUNC(order_date) = DATE '2025-01-05';-- ĐÚNG — so sánh trực tiếp trên cột
SELECT order_id FROM orders
WHERE order_date >= DATE '2025-01-05'
AND order_date < DATE '2025-01-06';Tạo index cho mọi cột. Việc đọc có nhanh hơn một chút, nhưng mỗi lần ghi
dữ liệu lại chậm đi vì Oracle phải cập nhật quá nhiều index. Chỉ tạo index cho cột hay dùng
trong WHERE và JOIN.
Tóm tắt
- Không có index thì Oracle đọc cả bảng để tìm.
- Index giúp tìm nhanh theo cột, đổi lại tốn dung lượng và làm ghi chậm hơn.
- Khoá chính và
UNIQUEtự có index, khoá ngoại thì không. - Đừng bọc hàm quanh cột có index trong
WHERE.
Tự kiểm tra
0/3 câuTrang tìm khách theo email chạy chậm, bảng customers có 2 triệu dòng. Nên làm gì trước tiên?
Có index trên cột name. Câu nào KHÔNG dùng được index đó?
Vì sao không nên tạo index cho mọi cột?