[Series] Database Internals - Bài 1: Query Planning & Optimizer – "Bộ não" chiến lược của DBMS
![[Series] Database Internals - Bài 1: Query Planning & Optimizer – "Bộ não" chiến lược của DBMS](/_next/image?url=https%3A%2F%2Fnllgiwbecqskpipvcvpt.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fblog-images%2F0.8228254913216192.png&w=3840&q=75)
Chào anh em, tiếp nối bài tổng quan, hôm nay mình cùng bắt đầu hành trình từ tầng cao nhất của hệ thống. Đây là nơi tiếp nhận những câu lệnh SQL dạng văn bản và biến chúng thành một kế hoạch thực thi chi tiết.
Khi anh em gửi một câu lệnh
SELECTvào hệ thống, DBMS không chạy nó ngay lập tức. Nó phải trải qua một quy trình kiểm duyệt và tính toán chiến lược để đảm bảo lấy được dữ liệu nhanh nhất có thể.

1. Parser và Binder: Những người gác cổng
Trước khi nghĩ đến việc chạy nhanh hay chậm, câu lệnh phải đảm bảo tính đúng đắn.
Parser (Phân tích cú pháp): Lớp này đóng vai trò như một trình biên dịch ngôn ngữ. Nó đọc chuỗi SQL và kiểm tra lỗi chính tả hoặc từ khóa. Nếu anh em gõ nhầm
SELETC * FROM..., Parser sẽ chặn lại ngay lập tức và trả về lỗi cú pháp. Kết quả đầu ra của nó thường là một cây phân tích cú pháp (Abstract Syntax Tree).Binder (Kiểm tra ngữ nghĩa): Có cây cú pháp rồi, Binder sẽ đối chiếu nó với Data Dictionary Manager (như trong sơ đồ thành phần bên dưới). Nó xác thực xem bảng
userscó tồn tại không, cộtagecó trong bảng đó không, và anh em có đủ quyền hạn để truy cập không.
Bên trong các tầng xử lý này thực chất là sự phối hợp của rất nhiều module nhỏ như Data Dictionary Manager hay Authorization Control.
2. Query Optimizer:
Đây chính là "ngôi sao" của tầng này. Nhiệm vụ của Optimizer là biến kế hoạch logic ở trên thành một Physical Plan (Kế hoạch vật lý) tối ưu nhất.
Hầu hết các DBMS hiện đại đều dùng mô hình Cost-based Optimization (CBO). Nghĩa là hệ thống sẽ không chọn bừa phương án thực thi, mà nó sẽ tính toán "chi phí" (thường đo bằng I/O đĩa và CPU) cho nhiều kịch bản khác nhau để chọn cái rẻ nhất.
👉 Ví dụ thực tế: Sự lựa chọn của Optimizer
Giả sử anh em cần tìm đơn hàng của một khách hàng cụ thể:
SQL
SELECT * FROM orders WHERE customer_id = 99;Optimizer sẽ cân nhắc giữa hai con đường chính:
Table Scan: Quét từ đầu đến cuối bảng
ordersđể tìm những dòng có ID bằng 99. Nếu bảng có 1 triệu dòng, chi phí sẽ rất lớn.Index Scan: Nếu có Index trên cột
customer_id, Optimizer sẽ dùng nó để nhảy thẳng đến vị trí dữ liệu cần tìm. Chi phí lúc này cực kỳ thấp.
Hệ thống sẽ dựa vào các Statistics (thống kê) về số lượng dòng, độ phân bổ dữ liệu để quyết định xem con đường nào là "rẻ" nhất.
3. Kết quả:
Sau cùng, bộ não Optimizer sẽ xuất bản ra một "bản thiết kế". Đây chính là kết quả cuối cùng của tầng Query Planning và là đầu vào cho tầng Operator Execution.
Giả sử anh em có một câu lệnh SQL kinh điển:
SQL
SELECT users.name
FROM users
JOIN orders ON users.id = orders.user_id
WHERE orders.price > 100;Sau khi tính toán các chỉ số về chi phí (Cost), Optimizer sẽ "vẽ" ra một cái cây kế hoạch vật lý (Physical Plan Tree) trông như thế này:
Giải mã các thành phần trong cây:
Nút Gốc (Root - Node 1): Đây là đích đến cuối cùng. Nó nhận dữ liệu từ cấp dưới và chỉ lọc ra đúng cột
nameđể trả về cho anh em.Nút Trung gian (Internal Nodes - Node 2 & 4):
Node 2 (Hash Join): Đóng vai trò bộ ghép nối. Nó lấy dữ liệu từ hai nhánh (users và orders) để khớp nối dựa trên ID.
Node 4 (Filter): Một trạm kiểm soát. Nó chỉ cho phép những bản ghi nào thỏa mãn điều kiện
price > 100đi qua để lên tới phép Join.
Nút Lá (Leaves - Node 3 & 5): Đây là nơi tiếp xúc trực tiếp với dữ liệu dưới đĩa.
Optimizer đã cực kỳ thông minh khi chọn Index Scan cho bảng
orders(Node 5) vì có điều kiện lọc theo giá, nhưng lại chọn Sequential Scan cho bảngusers(Node 3) vì không có điều kiện lọc nào cụ thể cho bảng này.
Nơi lưu trữ cấu trúc cây ( kết quả ): Lưu trên RAM trong một vùng nhớ gọi là Plan Cache
- Cơ chế Hashing: Mỗi khi anh em gửi một câu SQL, Database sẽ băm (hash) chuỗi text đó thành một mã định danh. Nếu mã này đã có trong Plan Cache, hệ thống sẽ lấy ngay "cái cây" cũ ra dùng mà không cần bắt Optimizer phải "vẽ" lại từ đầu.
- Tính tạm thời: Vì nằm trên RAM, nên nếu anh em khởi động lại (restart) Database, toàn bộ các bản kế hoạch này sẽ mất hết. Optimizer sẽ phải tính toán lại cho những lượt truy vấn đầu tiên.
Tổng kết
Tầng Query Planning là nơi thể hiện trí tuệ của DBMS. Nó đảm bảo chúng ta có một bản thiết kế thi công chi tiết (Physical Plan) trước khi thực sự chạm vào dữ liệu.
Chúng ta vừa đi qua tầng cao nhất trong mô hình 5 lớp. Tiếp theo, ai sẽ là người thực thi bản kế hoạch này?
Trong bài tiếp theo, mình sẽ cùng anh em xuống tầng 2: Operator Execution — Nơi các phép toán Join, Sort thực sự diễn ra và cách hệ thống quản lý giao dịch để giữ cho dữ liệu luôn nhất quán.



![[Series] Database Internals - Bài 1: Tại sao RDBMS lưu dữ liệu khác với File thông thường?](/_next/image?url=https%3A%2F%2Fnllgiwbecqskpipvcvpt.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fblog-images%2F0.5746714924169717.png&w=3840&q=75)
![[Series] Database Internals - Bài 2: Giải mã "Thùng sách" – Nghệ thuật sắp xếp Slotted Page Layout](/_next/image?url=https%3A%2F%2Fnllgiwbecqskpipvcvpt.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fblog-images%2F0.30555181914624063.png&w=3840&q=75)