Quy trình chẩn đoán:
1. Tìm truy vấn chậm: bật log_min_duration_statement hoặc dùng pg_stat_statements để thấy truy vấn tốn tài nguyên nhất.
2. EXPLAIN (ANALYZE, BUFFERS): xem plan thật — có Seq Scan trên bảng lớn không, join kiểu gì, rows ước lượng lệch thực tế không, có sort/hash tràn đĩa không.
3. Sửa theo dấu hiệu:
- Thiếu index trên cột lọc/join → thêm index (cân nhắc composite/covering).
- Thống kê cũ (ước lượng lệch) → chạy ANALYZE.
- Hàm bọc quanh cột (WHERE lower(email)=...) làm mất index → dùng expression index hoặc viết lại điều kiện sargable.
- SELECT * khi chỉ cần vài cột → chọn đúng cột, mở đường cho index-only scan.
- N+1 từ ORM → JOIN/batch.
- Trả quá nhiều hàng → phân trang (keyset), LIMIT.
4. Đo lại sau mỗi thay đổi.
Nguyên tắc: đo trước, đoán sau — luôn dựa vào EXPLAIN thay vì phỏng đoán.