GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Câu hỏi kinh điển mà một nhà phát triển đặt ra cho DBA của mình hoặc một chủ doanh nghiệp đặt ra cho nhà tư vấn PostgreSQL hầu như luôn có vẻ giống nhau: “Tại sao các yêu cầu mất nhiều thời gian để hoàn thành trên cơ sở dữ liệu?”

Nhóm lý do truyền thống:

  • thuật toán kém hiệu quả
    khi bạn quyết định THAM GIA một số CTE trên hàng chục nghìn bản ghi
  • số liệu thống kê không liên quan
    nếu mức phân phối dữ liệu thực tế trong bảng rất khác so với dữ liệu được ANALYZE thu thập lần trước
  • "cắm" vào tài nguyên
    và không còn đủ sức mạnh tính toán chuyên dụng của CPU, hàng gigabyte bộ nhớ liên tục bị bơm hoặc đĩa không thể đáp ứng mọi “mong muốn” của cơ sở dữ liệu
  • chặn lại từ các quá trình cạnh tranh

Và nếu các khối khá khó nắm bắt và phân tích, thì chúng ta cần mọi thứ khác kế hoạch truy vấn, có thể thu được bằng cách sử dụng GIẢI THÍCH toán tử (Tất nhiên, tốt hơn hết là GIẢI THÍCH ngay lập tức (PHÂN TÍCH, ĐỆM) ...) hoặc mô-đun auto_explain.

Nhưng, như đã nêu trong cùng một tài liệu,

“Hiểu được một kế hoạch là một nghệ thuật và để thành thạo nó cần phải có một lượng kinh nghiệm nhất định…”

Nhưng bạn có thể làm mà không cần nó nếu bạn sử dụng đúng công cụ!

Một kế hoạch truy vấn thường trông như thế nào? Một cái gì đó như thế:

Index Scan using pg_class_relname_nsp_index on pg_class (actual time=0.049..0.050 rows=1 loops=1)
  Index Cond: (relname = $1)
  Filter: (oid = $0)
  Buffers: shared hit=4
  InitPlan 1 (returns $0,$1)
    ->  Limit (actual time=0.019..0.020 rows=1 loops=1)
          Buffers: shared hit=1
          ->  Seq Scan on pg_class pg_class_1 (actual time=0.015..0.015 rows=1 loops=1)
                Filter: (relkind = 'r'::"char")
                Rows Removed by Filter: 5
                Buffers: shared hit=1

hoặc như thế này:

"Append  (cost=868.60..878.95 rows=2 width=233) (actual time=0.024..0.144 rows=2 loops=1)"
"  Buffers: shared hit=3"
"  CTE cl"
"    ->  Seq Scan on pg_class  (cost=0.00..868.60 rows=9972 width=537) (actual time=0.016..0.042 rows=101 loops=1)"
"          Buffers: shared hit=3"
"  ->  Limit  (cost=0.00..0.10 rows=1 width=233) (actual time=0.023..0.024 rows=1 loops=1)"
"        Buffers: shared hit=1"
"        ->  CTE Scan on cl  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.021..0.021 rows=1 loops=1)"
"              Buffers: shared hit=1"
"  ->  Limit  (cost=10.00..10.10 rows=1 width=233) (actual time=0.117..0.118 rows=1 loops=1)"
"        Buffers: shared hit=2"
"        ->  CTE Scan on cl cl_1  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.001..0.104 rows=101 loops=1)"
"              Buffers: shared hit=2"
"Planning Time: 0.634 ms"
"Execution Time: 0.248 ms"

Nhưng việc đọc kế hoạch bằng văn bản “từ tờ giấy” rất khó và không rõ ràng:

  • được hiển thị trong nút tổng hợp theo tài nguyên cây con
    nghĩa là, để hiểu mất bao nhiêu thời gian để thực thi một nút cụ thể hoặc chính xác việc đọc dữ liệu từ bảng này lấy dữ liệu từ đĩa ra sao, bạn cần bằng cách nào đó trừ cái này khỏi cái kia
  • thời gian nút là cần thiết nhân với vòng lặp
    vâng, phép trừ không phải là thao tác phức tạp nhất phải được thực hiện “trong đầu” - xét cho cùng, thời gian thực hiện được biểu thị là trung bình cho một lần thực hiện một nút và có thể có hàng trăm nút đó
  • chà, và tất cả những điều này cùng nhau ngăn cản chúng ta trả lời câu hỏi chính - vậy ai "liên kết yếu nhất"?

Khi chúng tôi cố gắng giải thích tất cả những điều này cho hàng trăm nhà phát triển của mình, chúng tôi nhận ra rằng nhìn từ bên ngoài thì nó trông giống như thế này:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Và điều đó có nghĩa là chúng ta cần...

Công cụ

Trong đó, chúng tôi đã cố gắng thu thập tất cả các cơ chế chính giúp hiểu “ai là người có lỗi và phải làm gì” theo kế hoạch và yêu cầu. Vâng, và chia sẻ một phần kinh nghiệm của bạn với cộng đồng.
Gặp gỡ và sử dụng - giải thích.tensor.ru

Khả năng hiển thị của các kế hoạch

Có dễ hiểu kế hoạch khi nó trông như thế này không?

Seq Scan on pg_class (actual time=0.009..1.304 rows=6609 loops=1)
  Buffers: shared hit=263
Planning Time: 0.108 ms
Execution Time: 1.800 ms

Không hẳn vậy.

Nhưng như thế này, ở dạng viết tắtkhi các chỉ số chính được tách ra thì rõ ràng hơn nhiều:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Nhưng nếu kế hoạch phức tạp hơn, anh ấy sẽ đến giải cứu. phân bố thời gian của piechart theo nút:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Chà, đối với những lựa chọn khó khăn nhất, anh ấy rất vội vàng giúp đỡ Biểu đồ tiến độ:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Ví dụ, có những tình huống không hề tầm thường khi một kế hoạch có thể có nhiều hơn một gốc thực sự:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói raGIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Manh mối cấu trúc

Chà, nếu toàn bộ cấu trúc của kế hoạch và những điểm yếu của nó đã được trình bày và nhìn thấy rõ ràng, tại sao không làm nổi bật chúng cho nhà phát triển và giải thích chúng bằng “tiếng Nga”?

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói raChúng tôi đã thu thập được vài chục mẫu đề xuất như vậy.

Trình lược tả truy vấn từng dòng

Bây giờ, nếu bạn áp dụng truy vấn ban đầu vào kế hoạch được phân tích, bạn có thể thấy lượng thời gian đã dành cho mỗi câu lệnh riêng lẻ - đại loại như thế này:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

...hoặc thậm chí như thế này:

GIẢI THÍCH điều gì im lặng và làm thế nào để nó nói ra

Thay thế các tham số vào một yêu cầu

Nếu bạn “đính kèm” không chỉ yêu cầu vào gói mà còn cả các tham số của nó từ dòng CHI TIẾT của nhật ký, bạn có thể sao chép thêm yêu cầu đó vào một trong các tùy chọn:

  • với sự thay thế giá trị trong truy vấn
    để thực hiện trực tiếp trên cơ sở của bạn và lập hồ sơ thêm

    SELECT 'const', 'param'::text;
  • với sự thay thế giá trị thông qua PREPARE/EXECUTE
    để mô phỏng công việc của bộ lập lịch, khi phần tham số có thể bị bỏ qua - ví dụ: khi làm việc trên các bảng được phân vùng

    DEALLOCATE ALL;
    PREPARE q(text) AS SELECT 'const', $1::text;
    EXECUTE q('param'::text);
    

Lưu trữ kế hoạch

Dán, phân tích, chia sẻ với đồng nghiệp! Các kế hoạch sẽ vẫn được lưu trữ và bạn có thể quay lại sau: giải thích.tensor.ru/archive

Nhưng nếu bạn không muốn người khác xem kế hoạch của mình, đừng quên đánh dấu vào ô “không xuất bản trong kho lưu trữ”.

Trong các bài viết sau tôi sẽ nói về những khó khăn và quyết định nảy sinh khi phân tích một kế hoạch.

Nguồn: www.habr.com

Thêm một lời nhận xét