PostgreSQL giải thích cho tôi biết chính xác là gì?


116

Đầu ra giải thích của MySQL khá đơn giản. PostgreSQL phức tạp hơn một chút. Tôi cũng không thể tìm thấy một nguồn nào tốt để giải thích nó.

Bạn có thể mô tả chính xác những gì giải thích đang nói hoặc ít nhất chỉ cho tôi theo hướng của một nguồn tài liệu tốt?

Câu trả lời:


50

Giải thích_EXPLAIN.pdf cũng có thể hữu ích.


64
Tôi không hiểu tại sao mọi người lại nghĩ rằng sàn trượt tạo ra tài liệu kỹ thuật tốt. Một đoạn video về buổi nói chuyện có thể hữu ích, nhưng mật độ thông tin của trang trình bày đó rất gần bằng không. Trong sáu slide đầu tiên (1/5 tổng số), có đúng 1 câu nội dung kỹ thuật: "• EXPLAIN hoạt động trên bất kỳ DML nào chứ không chỉ CHỌN (tức là CẬP NHẬT, XÓA và CHÈN)". Sự hiểu lầm lớn nhất của tôi là thời gian "khởi động" nghĩa là gì, và điều đó không được giải thích ở đâu trong ~ 30 trang trình bày này.
Mark E. Haase

80

Phần tôi luôn cảm thấy khó hiểu là chi phí khởi động và tổng chi phí. Tôi Google điều này mỗi khi tôi quên nó, nó đưa tôi trở lại đây, điều này không giải thích 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 thu thập được từ tài liệu PostgresEXPLAIN , được giải thích khi tôi hiểu nó.

Đây là một ví dụ từ một ứng dụng quản lý 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)

Đây là giải thích bằng hình ảnh từ PgAdmin:

giải thích đồ họa của truy vấn đầu tiên

(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 phí.)

Chi phí được biểu diễn dưới dạng một bộ giá trị, ví dụ như chi phí LIMITcost=0.00..3.39và chi phí quét tuần tự postcost=0.00..15629.12. Số đầu tiên trong bộ giá trị là chi phí khởi động và số thứ hai là tổng chi phí . Bởi vì tôi đã sử dụng EXPLAINvà không sử dụng EXPLAIN ANALYZE, những chi phí này là ước tính, không phải là thước đo 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 lượng thời gian trước khi thành phần đó bắt đầu . Nó đại diện cho khoảng thời gian từ khi thành phần bắt đầu thực thi (đọc dữ liệu) đến 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 thi của thành phần, từ khi nó bắt đầu đọc dữ liệu đến khi nó kết thúc việc ghi đầu ra của nó.

Một điều phức tạp là chi phí của mỗi nút "cha" bao gồm chi phí của các nút con của nó. Trong biểu diễn văn bản, cây được biểu diễn bằng cách thụt lề, ví dụ như LIMITlà một nút cha và Seq Scanlà nút con của nó. Trong biểu diễn PgAdmin, các mũi tên trỏ từ con đến cha - hướng của luồng dữ liệu - có thể phản trực giác nếu bạn đã quen thuộc 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 nút cha 3.39nhỏ hơn nhiều so với tổng chi phí của nó 15629.12. Tổng chi phí không bao gồm bởi vì một thành phần như LIMITkhông cần phải xử lý toàn bộ đầu vào của nó. Xem EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;ví dụ trong tài liệu PostgresEXPLAIN .

Trong ví dụ trên, thời gian khởi động bằng 0 đối với cả hai thành phần, vì cả hai thành phần đều không cần thực hiện bất kỳ quá trình xử lý nào trước khi bắt đầu ghi các hàng: quét tuần tự đọc hàng đầu tiên của bảng và phát ra. Các LIMITlần đọc dò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 xử lý trước khi nó có thể bắt đầu xuất ra bất kỳ hàng nào? Có rất nhiều lý do có thể xảy ra, nhưng hãy xem một ví dụ rõ ràng. Đây là cùng một truy vấn từ trước nhưng bây giờ chứa một ORDER BYmệnh đề:

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à về mặt đồ họa:

giải thích đồ họa của truy vấn thứ hai

Một lần nữa, quá trình quét tuần tự được bật postkhông có chi phí khởi động: nó bắt đầu xuất các hàng ngay lập tức. Nhưng việc sắp xếp có một chi phí khởi động đáng kể 23283.24vì nó phải sắp xếp toàn bộ bảng trước khi nó có thể xuất ra dù chỉ một hàng . Tổng chi phí sắp xếp 23859.27chỉ cao hơn một chút so với chi phí khởi động, phản ánh thực tế là một 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.24chính xác bằng thời gian khởi động của loại. Điều này không phải vì LIMITbản thân nó có thời gian khởi động cao. Nó thực sự không có thời gian khởi động tự nó, nhưng tổng EXPLAINhợp tất cả các chi phí con cho mỗi phụ huynh, vì vậy LIMITthời gian khởi động bao gồm tổng thời gian khởi động của các con của nó.

Việc tổng hợp 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ụ: LIMITthời gian khởi động của chúng tôi là 0, nhưng điều đó không rõ ràng ở 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 giải thích.depesz.com , một công cụ do Hubert Lubaczewski (hay còn gọi là depesz) tạo ra để giúp hiểu EXPLAIN- trong số những thứ khác - trừ chi phí con khỏi chi phí cha mẹ. Anh ấy đề cập đến một số phức tạp khác trong một bài đăng blog ngắn về công cụ của mình.


4
Cảm ơn vì điều này. Tôi cũng muốn thêm một trình hiển thị giải thích thực hiện công việc hiển thị đầu ra (imo) thậm chí còn tốt hơn. tatiyants.com/pev
Jonathan Porter

Câu trả lời chính xác. Và nhận xét của bạn rằng chi phí khởi động bao gồm thời gian trả về hàng đầu tiên đã giúp tôi hiểu tại sao chi phí khởi động cho Sắp xếp không chỉ là 15629.12.
Joel Wigton

43

Nó thực hiện từ thụt lề nhiều nhất đến thụt lề ít nhất và tôi tin rằng từ cuối kế hoạch đến đầu. (Vì vậy, nếu có hai phần được thụt lề, phần nằm ở phía dưới trang sẽ thực thi đầu tiên, sau đó khi chúng gặp các phần khác thực thi, thì quy tắc kết hợp chúng sẽ thực thi.)

Ý tưởng là ở mỗi bước có 1 hoặc 2 bộ dữ liệu đến và được xử lý theo quy tắc nào đó. Nếu chỉ một tập dữ liệu, thì thao tác đó được thực hiện với tập dữ liệu đó. (Ví dụ: quét chỉ mục để tìm ra những hàng bạn muốn, lọc tập dữ liệu hoặc sắp xếp nó.) Nếu hai, hai tập dữ liệu là hai thứ được thụt vào sâu hơn và chúng được nối với nhau theo quy tắc bạn thấy. Ý nghĩa của hầu hết các quy tắc có thể dễ dàng đoán ra một cách hợp lý (đặc biệt nếu bạn đã đọc một loạt các kế hoạch giải thích trước đó), tuy nhiên, bạn có thể thử xác minh các mục riêng lẻ bằng cách xem trong tài liệu hoặc (dễ dàng hơn) bằng cách chỉ cần ném cụm từ vào Google cùng với một vài từ khóa như EXPLAIN.

Đây rõ ràng không phải là một lời giải thích đầy đủ, nhưng nó cung cấp đủ ngữ cảnh mà bạn thường có thể tìm ra bất cứ điều gì bạn muốn. Ví dụ: hãy xem xét kế hoạch này từ một cơ sở dữ liệu thực tế:

explain analyze
select a.attributeid, a.attributevalue, b.productid
from orderitemattribute a, orderitem b
where a.orderid = b.orderid
and a.attributeid = 'display-album'
and b.productid = 'ModernBook';

------------------------------------------------------------------------------------------------------------------------------------------------------------

 Merge Join  (cost=125379.14..125775.12 rows=3311 width=29) (actual time=841.478..841.478 rows=0 loops=1)
   Merge Cond: (a.orderid = b.orderid)
   ->  Sort  (cost=109737.32..109881.89 rows=57828 width=23) (actual time=736.163..774.475 rows=16815 loops=1)
         Sort Key: a.orderid
         Sort Method:  quicksort  Memory: 1695kB
         ->  Bitmap Heap Scan on orderitemattribute a  (cost=1286.88..105163.27 rows=57828 width=23) (actual time=41.536..612.731 rows=16815 loops=1)
               Recheck Cond: ((attributeid)::text = 'display-album'::text)
               ->  Bitmap Index Scan on (cost=0.00..1272.43 rows=57828 width=0) (actual time=25.033..25.033 rows=16815 loops=1)
                     Index Cond: ((attributeid)::text = 'display-album'::text)
   ->  Sort  (cost=15641.81..15678.73 rows=14769 width=14) (actual time=14.471..16.898 rows=1109 loops=1)
         Sort Key: b.orderid
         Sort Method:  quicksort  Memory: 76kB
         ->  Bitmap Heap Scan on orderitem b  (cost=310.96..14619.03 rows=14769 width=14) (actual time=1.865..8.480 rows=1114 loops=1)
               Recheck Cond: ((productid)::text = 'ModernBook'::text)
               ->  Bitmap Index Scan on id_orderitem_productid  (cost=0.00..307.27 rows=14769 width=0) (actual time=1.431..1.431 rows=1114 loops=1)
                     Index Cond: ((productid)::text = 'ModernBook'::text)
 Total runtime: 842.134 ms
(17 rows)

Hãy thử đọc nó cho chính mình và xem nó có ý nghĩa không.

Những gì tôi đọc được là cơ sở dữ liệu đầu tiên quét id_orderitem_productidchỉ mục, sử dụng chỉ mục đó để tìm các hàng mà nó muốn orderitem, sau đó sắp xếp tập dữ liệu đó bằng cách sử dụng nhanh chóng (loại được sử dụng sẽ thay đổi nếu dữ liệu không vừa với RAM), sau đó đặt điều đó sang một bên.

Tiếp theo, nó quét orditematt_attributeid_idxđể tìm các hàng mà nó muốn orderitemattributevà sau đó sắp xếp tập dữ liệu đó bằng cách sử dụng nhanh chóng.

Sau đó, nó lấy hai tập dữ liệu và hợp nhất chúng. (Phép nối hợp nhất là một loại hoạt động "nén" trong đó nó sẽ chuyển hai tập dữ liệu được sắp xếp song song, tạo ra hàng đã nối khi chúng khớp với nhau.)

Như tôi đã nói, bạn làm việc thông qua kế hoạch từ phần bên trong đến phần bên ngoài, từ dưới lên trên.


22

Depesz cũng có một công cụ trợ giúp trực tuyến, công cụ này sẽ làm nổi bật những phần đắt giá của kết quả phân tích.

cũng có một, đây là kết quả tương tự , tôi làm rõ hơn vấn đề nằm ở đâu.


20
Giải thích-analyze.info có vẻ không hoạt động, nhưng tôi đồng ý rằng giải thích.depesz.com rất hữu ích.
benvolioT

13

PgAdmin sẽ hiển thị cho bạn một biểu diễn đồ họa của kế hoạch giải thích. Chuyển đổi qua lại giữa hai kiểu thực sự có thể giúp bạn hiểu ý nghĩa của biểu diễn văn bản. Tuy nhiên, nếu bạn chỉ muốn biết nó sẽ làm gì, bạn có thể luôn sử dụng GUI.



0

Nếu bạn cài đặt pgadmin, có một nút Giải thích cũng như cung cấp đầu ra văn bản vẽ sơ đồ về những gì đang xảy ra, hiển thị các bộ lọc, sắp xếp và hợp nhất tập hợp con mà tôi thấy thực sự hữu ích để xem điều gì đang xảy ra.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.