Lập trình 22/09/2026 6 phút

Tối ưu query từ đầu tới cuối: cây quyết định, checklist, và một query từ 51ms xuống 3.7ms

Loạt SQL sâu đi qua 11 công cụ; bài cuối ghép chúng thành một quy trình. Query chậm không phải chuyện thử-sai — có cây quyết định rõ ràng bắt đầu từ EXPLAIN ANALYZE. Bài này đo thật một query chậm (JOIN + filter + ORDER BY LIMIT trên 2 triệu dòng): viết sargable một mình không đủ (vẫn 51ms), nhưng sargable + index đúng + ANALYZE đưa xuống 3.66ms — nhanh 14 lần. Kèm cây quyết định và checklist tối ưu.

Cơ sở dữ liệu 29/08/2026 10 phút

Cùng bài top-3 mỗi nhân viên: SQL mất 78 ms, kéo về ứng dụng tự tính mất 1.070 ms và 25 MB qua mạng

Window function giải lớp bài toán GROUP BY không giải nổi: xếp hạng trong nhóm, so với dòng trước, cộng dồn. Tôi đo chi phí thật của chúng, so với LATERAL và với cách kéo dữ liệu về ứng dụng tự tính — và bất ngờ là LATERAL nhanh gần gấp đôi window function.

Cơ sở dữ liệu 29/08/2026 10 phút

Gấp 64 lần bộ nhớ cho GROUP BY chỉ nhanh hơn 3% — vì chi phí nằm ở số nhóm, không ở số dòng

GROUP BY dễ viết nhất mà khó đoán chi phí nhất. Tôi đo lượng bộ nhớ nó thật sự dùng và tìm ra: chi phí phụ thuộc số nhóm đầu ra chứ không phải số dòng đầu vào, cho thêm bộ nhớ gần như vô ích, và một chỉ mục cho 2× tốc độ với 0 bộ nhớ.

Cơ sở dữ liệu 29/08/2026 10 phút

Trang cuối đọc đủ 5 triệu dòng để trả về 20 — và OFFSET còn âm thầm bỏ sót dữ liệu khi có người xoá bài

LIMIT 20 OFFSET 1000 là cách phân trang ai cũng viết đầu tiên: đúng, ngắn, và chậm dần theo số trang — nhưng chậm bao nhiêu thì ít ai đo. Tôi đo, và đo cả một lỗi nghiêm trọng hơn chuyện chậm: OFFSET neo vào vị trí, mà vị trí thì đổi khi dữ liệu đổi.

Cơ sở dữ liệu 29/08/2026 10 phút

JSONB tốn gấp đôi chỗ, đếm chậm 38 lần, ghi tốn 6,6 lần WAL — và vẫn có đúng một chỗ nó là lựa chọn duy nhất

JSONB rất tiện: không cần ALTER TABLE, thêm trường lúc nào cũng được. Tôi dựng hai bảng cùng dữ liệu — một cột thường, một JSONB — để đo cái giá của sự tiện đó, và tìm ra ranh giới rõ ràng giữa lúc nên dùng và lúc phải trả giá đắt.