Phần tôi luôn thấy khó hiểu là chi phí khởi động so với tổng chi phí. Tôi Google này mỗi khi tôi quên nó, điều đó đưa tôi trở lại đây, điều này không giải thích được sự khác biệt, đó là lý do tại sao tôi viết câu trả lời này. Đây là những gì tôi đã lượm lặt từ số Postgres EXPLAIN
documentation, giải thích khi tôi hiểu nó.
Dưới đây là một ví dụ từ một ứng dụng quản lý một diễn đàn:
EXPLAIN SELECT * FROM post LIMIT 50;
Limit (cost=0.00..3.39 rows=50 width=422)
-> Seq Scan on post (cost=0.00..15629.12 rows=230412 width=422)
Dưới đây là lời giải thích đồ họa từ pgAdmin:
(Khi bạn đang sử dụng pgAdmin, bạn có thể trỏ chuột vào một thành phần để đọc chi tiết chi tiết.)
Chi phí được biểu thị dưới dạng một bộ dữ liệu, ví dụ: chi phí của LIMIT
là cost=0.00..3.39
và chi phí quét tuần tự post
là cost=0.00..15629.12
. Số đầu tiên trong tuple là chi phí khởi động và số thứ hai là tổng chi phí . Bởi vì tôi đã sử dụng EXPLAIN
và không phải EXPLAIN ANALYZE
, các chi phí này là ước tính, không phải là các biện pháp thực tế.
- Chi phí khởi động là một khái niệm phức tạp. Nó không chỉ đại diện cho khoảng thời gian trước thành phần đó bắt đầu. Nó đại diện cho khoảng thời gian giữa khi thành phần bắt đầu thực thi (đọc dữ liệu) và khi thành phần xuất ra hàng đầu tiên của nó.
- Tổng chi phí là toàn bộ thời gian thực hiện của thành phần, từ khi nó bắt đầu đọc dữ liệu đến khi nó kết thúc ghi đầu ra của nó.
Là một biến chứng, mỗi chi phí của nút "cha mẹ" đều bao gồm chi phí của các nút con của nó. Trong phần trình bày văn bản, cây được biểu diễn bằng thụt đầu dòng, ví dụ: LIMIT
là một nút cha và Seq Scan
là con của nó. Trong biểu diễn PgAdmin, các mũi tên trỏ từ con sang mẹ - hướng của luồng dữ liệu - điều này có thể phản trực giác nếu bạn quen với lý thuyết đồ thị.
Tài liệu nói rằng chi phí bao gồm tất cả các nút con, nhưng lưu ý rằng tổng chi phí của phụ huynh 3.39
nhỏ hơn nhiều so với tổng chi phí của nó là 15629.12
. Tổng chi phí không được bao gồm bởi vì một thành phần như LIMIT
không cần xử lý toàn bộ đầu vào của nó. Xem ví dụ EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;
trong Postgres EXPLAIN
documentation. Trong ví dụ trên, thời gian khởi động là 0 cho cả hai thành phần, vì không thành phần nào cần thực hiện bất kỳ quá trình xử lý nào trước khi bắt đầu viết hàng: quét tuần tự đọc hàng đầu tiên của bảng và phát ra nó. Các LIMIT
đọc hàng đầu tiên của nó và sau đó phát ra nó.
Khi nào một thành phần cần thực hiện nhiều quá trình xử lý trước khi có thể bắt đầu xuất bất kỳ hàng nào?Có rất nhiều lý do có thể, nhưng hãy xem một ví dụ rõ ràng. Dưới đây là cùng một truy vấn từ trước nhưng bây giờ chứa một ORDER BY
khoản:
EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;
Limit (cost=23283.24..23283.37 rows=50 width=422)
-> Sort (cost=23283.24..23859.27 rows=230412 width=422)
Sort Key: body
-> Seq Scan on post (cost=0.00..15629.12 rows=230412 width=422)
Và đồ họa:
Một lần nữa, quá trình quét tuần tự trên post
không có chi phí khởi động: nó bắt đầu xuất ra hàng ngay lập tức . Nhưng loại này có chi phí khởi động đáng kể 23283.24
vì nó phải sắp xếp toàn bộ bảng trước khi nó có thể xuất ra ngay cả một hàng đơn. Tổng chi phí của loại 23859.27
chỉ cao hơn một chút so với chi phí khởi động, phản ánh thực tế là khi toàn bộ tập dữ liệu đã được sắp xếp, dữ liệu được sắp xếp có thể được phát ra rất nhanh.
Lưu ý rằng thời gian khởi động của LIMIT
23283.24
chính xác bằng thời gian khởi động sắp xếp. Điều này không phải vì bản thân có một thời gian khởi động cao. Nó thực sự không có thời gian khởi động của chính nó, nhưng EXPLAIN
cuộn lên tất cả các chi phí con cho mỗi phụ huynh, do đó, thời gian khởi động LIMIT
bao gồm tổng thời gian khởi động của các con của nó.
Việc cuộn chi phí này có thể gây khó khăn cho việc hiểu chi phí thực hiện của từng thành phần riêng lẻ. Ví dụ: LIMIT
của chúng tôi không có thời gian khởi động, nhưng điều đó không rõ ràng ngay từ cái nhìn đầu tiên. Vì lý do này, một số người khác liên kết với explain.depesz.com, một công cụ được tạo bởi Hubert Lubaczewski (a.k.a. depesz) giúp hiểu được EXPLAIN
bởi - trong số những thứ khác - trừ đi chi phí con từ chi phí gốc. Ông đề cập đến một số phức tạp khác trong a short blog post về công cụ của mình.
Tôi băn khoăn tại sao mọi người nghĩ rằng trang trình bày làm cho tài liệu kỹ thuật tốt. Video của cuộc nói chuyện có thể hữu ích, nhưng mật độ thông tin của bản chiếu đó rất gần bằng không. Trong sáu slide đầu tiên (1/5 của tổng số), có chính xác 1 câu nội dung kỹ thuật: "• GIẢI THÍCH làm việc trên bất kỳ DML không chỉ SELECT (tức là UPDATE, DELETE, và INSERT)". Sự hiểu lầm lớn nhất của tôi là những gì "khởi động" thời gian có nghĩa là, và đó là không giải thích bất cứ nơi nào trong ~ 30 slide. –