Subquery - Không chậm như bạn nghĩ

“Subquery chậm” là thiên kiến phổ biến. Chúng chậm vì THIẾU INDEX, không phải vì bản chất của subquery.

Independent Subquery

Chạy 1 lần duy nhất, kết quả thay thế vào query chính:

SELECT * FROM products
WHERE remaining > 500 AND category_id = (
    SELECT category_id FROM categories
    WHERE type = 'book' AND name = 'Science fiction'
);
-- Index cho subquery:    (type, name) trên categories
-- Index cho outer query: (category_id, remaining) trên products

Dependent Subquery

Chạy lặp lại cho mỗi row - giống join (Nested Loop Join):

SELECT * FROM products
WHERE remaining = 0 AND EXISTS (
    SELECT * FROM sales
    WHERE created_at >= '2023-01-01' AND product_id = products.product_id
);
-- Index cho outer:    (remaining) trên products
-- Index cho subquery: (product_id, created_at) trên sales

Tip: EXISTS tự động dừng sau khi tìm thấy 1 row match (giống có LIMIT 1 ngầm). Nhưng vẫn nên tạo index theo nguyên tắc range condition để tối ưu.

Nguyên tắc chung

Xem mỗi subquery như một query độc lập cần index riêng - giống hệt tư duy với join: phân tách, tạo index cho từng phần.

Liên quan