PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL gan ruột:“Resjunk” là gì?

Hiện tại, tôi đang nghiên cứu trình phân tích cú pháp PostgreSQL, trình ghi lại truy vấn và trình lập kế hoạch truy vấn, như một phần của công việc về bảo mật cấp hàng cho dự án AXLE. Khi tôi nhận thấy rằng có một số tài liệu tuyệt vời về cấu trúc và quy trình tổng thể nhưng không nhiều về một số chi tiết, tôi nghĩ rằng tôi sẽ bắt đầu đăng về một số góc khó hiểu hơn.

Nếu bạn không quan tâm đến mã nguồn PostgreSQL và hoạt động bên trong của nó, bạn có thể ngừng đọc ngay bây giờ.

gỡ bỏ

Chủ đề của ngày hôm nay là thuật ngữ "resjunk", dùng để chỉ resjunk thuộc tính target-list. Bạn sẽ thấy thuật ngữ này xuyên suốt người lập kế hoạch và người viết lại, thường là kiến ​​thức giả định. Tên không phải là cực kỳ hữu ích.

hủy bỏ các cột được mô tả trong src / backend / execute / executeJunk.c , nơi có nhận xét chi tiết vừa phải. Tuy nhiên, nó không thực sự giải thích được những ý tưởng bao quát.

Khái niệm là đôi khi PostgreSQL cần theo dõi thông tin trên từng tuple không phải là một phần của kết quả truy vấn. Đó có thể là một khóa sắp xếp không thuộc danh sách chọn, một kết quả trung gian từ một truy vấn con được sử dụng làm bộ lọc sau đó bị loại bỏ hoặc nó có thể là một cột nội bộ như ctid không được hiển thị cho người dùng.

Các nút kế hoạch có danh sách mục tiêu - đây là danh sách các cột do nút kế hoạch đó xuất ra. Đối với một bài kiểm tra SELECT a, b FROM đơn giản các cột a b sẽ xuất hiện trong danh sách mục tiêu của chỉ mục hoặc nút kế hoạch seqscan cho truy vấn. Bạn có thể tự mình quan sát điều này bằng cách bật ghi nhật ký kế hoạch, theo đầu ra được cắt sau:

regress=> CREATE TABLE 
regress=> SET enable_print_plan = on;
regress=> SET client_min_messages = debug;
regress=> SELECT a, b FROM test;
LOG:  plan:
DETAIL:     {PLANNEDSTMT 
   :commandType 1 
   :queryId 0 
   ....
   :planTree 
      {SEQSCAN 
      :startup_cost 0.00 
      :total_cost 29.40 
      :plan_rows 1940 
      :plan_width 12 
      :targetlist (
         {TARGETENTRY 
         :expr 
            {VAR 
            :varno 1 
            :varattno 1 
            ...
            :location 7
            }
         ...
         :resjunk false
         }
         {TARGETENTRY 
         :expr 
            {VAR 
            :varno 1 
            :varattno 2 
            ...
            :location 10
            }
         ....
         :resjunk false
         }
      )
      :qual  
      :lefttree  
      :righttree  
      :initPlan  
      :extParam (b)
      :allParam (b)
      :scanrelid 1
      }
   :rtable (
      {RTE 
      :alias  
      :eref 
         {ALIAS 
         :aliasname test 
         :colnames ("a" "b")
         }
      ...
      :selectedCols (b 9 10)
      :modifiedCols (b)
      }
   )
   ....
   }

Đó là kế hoạch chi tiết cho:

                       QUERY PLAN                       
--------------------------------------------------------
 Seq Scan on test  (cost=0.00..29.40 rows=1940 width=8)

Trong đó, bạn sẽ thấy rằng CHỌN có hai mục nhập trong danh sách mục tiêu, một mục cho mỗi cột. cũng không phải là rác vì cả hai đều được xuất ra bởi truy vấn.

Điều gì sẽ xảy ra nếu chúng ta thêm sắp xếp theo cột c , không có trong SELECT -list, chúng tôi sẽ thấy một cột mới được thêm vào danh sách mục tiêu và được đánh dấu là bị hủy bỏ:

regress=> SELECT a, b FROM test ORDER BY c;
LOG:  plan:
DETAIL:     {PLANNEDSTMT 
   :commandType 1 
   ....
   :planTree 
      {SORT 
      ....
      :targetlist (
         {TARGETENTRY 
         :expr 
            {VAR 
            :varno 65001 
            :varattno 1
            ...
            }
         :resno 1 
         :resname a 
         ...
         :resjunk false
         }
         {TARGETENTRY 
         :expr 
            {VAR 
            :varno 65001 
            :varattno 2 
            ...
            }
         :resno 2 
         :resname b 
         ....
         :resjunk false
         }
         {TARGETENTRY 
         :expr 
            {VAR 
            :varno 65001 
            :varattno 3 
            ...
            }
         :resno 3 
         :resname  
         ....
         :resjunk true
         }
      )
      :qual  
      :lefttree 
         {SEQSCAN 
         ...
         :targetlist (
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 1 
               ...
               }
            :resno 1 
            ...
            :resjunk false
            }
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 2 
               ...
               }
            :resno 2 
            ...
            :resjunk false
            }
            {TARGETENTRY 
            :expr 
               {VAR 
               :varno 1 
               :varattno 3 
               ...
               }
            :resno 3
            ...
            :resjunk true
            }
         )
         ....
      }
   :rtable (
      {RTE 
      :alias  
      :eref 
         {ALIAS 
         :aliasname test 
         :colnames ("a" "b" "c")
         }
      ....
      :selectedCols (b 9 10 11)
      :modifiedCols (b)
      }
   )
   ....
   }

cho kế hoạch truy vấn:

                          QUERY PLAN                           
---------------------------------------------------------------
 Sort  (cost=135.34..140.19 rows=1940 width=12)
   Sort Key: c
   ->  Seq Scan on test  (cost=0.00..29.40 rows=1940 width=12)
(3 rows)

Vì vậy, c được đánh dấu là hủy bỏ bởi vì nó là một khóa sắp xếp không nằm trong kết quả cuối cùng của kế hoạch.

Bạn cũng sẽ thấy ctid đã đánh dấu hủy bỏ trong UPDATE XÓA kế hoạch vì những lý do tương tự - phần đọc của kế hoạch tìm nạp các hàng để sửa đổi và các ID tuple của chúng; những thứ này được kéo vào một MODIFYTABLE ngoài cùng nhất nút kế hoạch cập nhật hàng để đánh dấu hàng đã bị xóa và nếu là bản cập nhật, hãy chèn một phiên bản mới của hàng.

Nghiên cứu dẫn đến những kết quả này đã nhận được tài trợ từ Chương trình khung thứ bảy của Liên minh châu Âu (FP7 / 2007-2013) theo thỏa thuận tài trợ số 318633


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhận bảng và cột sở hữu một chuỗi

  2. Về lợi ích của các đường dẫn được sắp xếp

  3. tính toán phần trăm thứ n trong postgresql

  4. GUI PostgreSQL nào tốt nhất? So sánh năm 2021

  5. Hiểu các loại ngày và chức năng của PostgreSQL (bằng các ví dụ)