Random I/O vs Sequential I/O
Random I/O (nhảy tới các vị trí khác nhau trên disk) đắt hơn Sequential I/O (đọc tuần tự) từ 10-100 lần. Đây là khái niệm vật lý nền tảng giải thích gần như MỌI quyết định của query optimizer.
Tại sao quan trọng
Khi database dùng index để tìm kết quả:
- Tìm con trỏ trong index → nhanh
- Nhảy tới bảng dữ liệu để lấy row → mỗi row ở một vị trí khác nhau trên disk = random I/O = TỐN KÉM
Khi phải load nhiều row từ table, chi phí “nhảy qua nhảy lại” vượt quá chi phí đọc tuần tự cả bảng → database chọn full table scan dù index tồn tại và match hoàn hảo.
Query WHERE is_processed = FALSE (match 200,000 / 1,000,000 rows):
Phương án 1: Dùng index
→ 200,000 lần nhảy random I/O = RẤT CAO
Phương án 2: Full table scan
→ Đọc tuần tự 1,000,000 dòng (sequential I/O) = THẤP HƠN
→ Database chọn phương án 2: BỎ QUA INDEX (và nó ĐÚNG!)Ngưỡng chuyển đổi
Khi query match khoảng 10-30% số row trở lên, full table scan thường nhanh hơn dùng index. Con số phụ thuộc:
- Loại disk (SSD nhanh hơn HDD ở random I/O)
- Kích thước row (row to = ít row/page = nhiều random I/O hơn)
- Bảng có fit trong RAM không
Tip PostgreSQL: random_page_cost mặc định 4.0 (tối ưu cho HDD). Dùng SSD hoặc data fit RAM → SET random_page_cost = 1.1; - giúp optimizer “tin tưởng” random I/O hơn → dùng index thường xuyên hơn.
Cách né random I/O
- Index-Only Query và Covering Index - bỏ hẳn bước nhảy vào bảng
- Partial Index - index nhỏ chỉ chứa phần dữ liệu quan tâm
- Pre-sort và Pre-aggregation - sắp dữ liệu vật lý liền kề nhau
Liên quan
- Query Optimizer và Cost Model - nơi chi phí I/O được đưa vào tính toán
- Low-Cardinality Column và Index - hệ quả trực tiếp của random I/O
- Có Index chưa chắc Query nhanh