Mỗi dòng trong plan là một node, thụt lề sâu hơn là node con chạy trước.
Đọc từ trong ra ngoài.
Seq Scan on orders (cost=0.00..18334.00 rows=12 width=64)
(actual time=0.021..412.883 rows=48219 loops=1)
Filter: (status = 'pending'::text)
Rows Removed by Filter: 951781
Planning Time: 0.184 ms
Execution Time: 448.220 mscost=start..totallà ước lượng của planner theo đơn vị nội bộ (không phải mili giây). Số đầu là chi phí tới khi trả dòng đầu tiên, số sau là tới dòng cuối. Chỉ dùng để so sánh giữa các plan, không có ý nghĩa tuyệt đối.actual time=start..totallà thời gian thật tính bằng ms, cho mỗi lần lặp. Nếuloops=100thì tổng thời gian của node đó làtotal × 100.rowstrongcostlà ước lượng;rowstrongactuallà thực tế.
Dấu hiệu quan trọng nhất là rows lệch. Ở ví dụ trên planner đoán 12 dòng nhưng thực tế 48219 — lệch 4000 lần. Ước lượng sai làm planner chọn nhầm chiến lược cho cả nhánh phía trên (nested loop thay vì hash join). Nguyên nhân thường gặp: thống kê cũ (chạy ANALYZE), cột có tương quan mà planner giả định độc lập (dùng CREATE STATISTICS), hoặc điều kiện phức tạp planner không ước lượng nổi.
Mẹo: dùng EXPLAIN (ANALYZE, BUFFERS) để thấy số trang đọc từ cache và từ đĩa — thường chỉ ra vấn đề rõ hơn cả thời gian. Lưu ý EXPLAIN ANALYZE thực thi thật truy vấn, nên với UPDATE/DELETE phải bọc trong transaction rồi ROLLBACK.