PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL हिम्मत:"रेसजंक" क्या है?

AXLE प्रोजेक्ट के लिए पंक्ति-स्तरीय सुरक्षा पर काम के हिस्से के रूप में, मैं इस समय PostgreSQL पार्सर, क्वेरी रीराइटर और क्वेरी प्लानर में जा रहा हूँ। जैसा कि मैंने देखा है कि समग्र संरचना और प्रवाह पर कुछ बेहतरीन दस्तावेज हैं, लेकिन कुछ विवरणों पर ज्यादा नहीं है, मैंने सोचा कि मैं कुछ अधिक भ्रमित करने वाले कोनों के बारे में पोस्ट करना शुरू कर दूंगा।

यदि आप PostgreSQL स्रोत कोड और इसकी आंतरिक कार्यप्रणाली में रुचि नहीं रखते हैं, तो आप अभी पढ़ना बंद कर सकते हैं।

रेसजंक

आज का विषय "रेसजंक" शब्द है, जिसका अर्थ है resjunk लक्ष्य-सूची विशेषता। आप इस शब्द को पूरे योजनाकार और पुनर्लेखक में देखेंगे, आमतौर पर कल्पित ज्ञान के रूप में। नाम बहुत मददगार नहीं है।

रेसजंक कॉलम src/backend/executor/execJunk.c में वर्णित हैं , जहां मामूली विस्तृत टिप्पणी है। हालांकि, यह वास्तव में व्यापक विचारों की व्याख्या नहीं करता है।

अवधारणा यह है कि कभी-कभी PostgreSQL को प्रति-ट्यूपल जानकारी का ट्रैक रखने की आवश्यकता होती है जो क्वेरी आउटपुट का हिस्सा नहीं है। यह एक सॉर्ट कुंजी हो सकती है जो चयन सूची का हिस्सा नहीं है, एक सबक्वेरी से एक मध्यवर्ती परिणाम जिसे फ़िल्टर के रूप में उपयोग किया जाता है और फिर छोड़ दिया जाता है, या यह ctid जैसा आंतरिक कॉलम हो सकता है। जो उपयोगकर्ताओं के सामने नहीं आता है।

योजना नोड्स में लक्ष्य सूचियां होती हैं - ये उस योजना नोड द्वारा आउटपुट कॉलम की सूचियां हैं। आसान परीक्षण से a, b चुनें . के लिए कॉलम a और b क्वेरी के लिए अनुक्रमणिका या seqscan योजना नोड की लक्ष्य-सूची में दिखाई देगा। आप निम्न ट्रिम किए गए आउटपुट के अनुसार, योजना लॉगिंग को सक्षम करके स्वयं इसका निरीक्षण कर सकते हैं:

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)
      }
   )
   ....
   }

इसके लिए विस्तृत योजना है:

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

इसमें आप देखेंगे कि SELECT लक्ष्य-सूची में दो प्रविष्टियाँ हैं, प्रत्येक स्तंभ के लिए एक। न तो रेसजंक . है चूंकि दोनों क्वेरी द्वारा आउटपुट हैं।

क्या होगा अगर हम c . कॉलम के आधार पर एक सॉर्ट जोड़ते हैं , जो SELECT . में नहीं है -सूची में, हम लक्ष्य सूची में जोड़ा गया एक नया कॉलम देखेंगे और इसे resjunk के रूप में चिह्नित करेंगे:

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)
      }
   )
   ....
   }

क्वेरी योजना के लिए:

                          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)

तो c resjunk . के रूप में चिह्नित है क्योंकि यह एक सॉर्ट कुंजी है जो अंतिम योजना आउटपुट का हिस्सा नहीं है।

आपको ctid . भी दिखाई देगा चिह्नित रेसजंक अद्यतन . में और हटाएं समान कारणों से योजनाएँ - योजना का पढ़ा हुआ भाग संशोधित करने के लिए पंक्तियों और उनकी टपल आईडी को प्राप्त करता है; इन्हें सबसे बाहरी MODIFYTABLE . में खींचा जाता है योजना नोड जो पंक्ति को अद्यतन करता है ताकि उसे हटाया गया चिह्नित किया जा सके और, यदि यह एक अद्यतन है, तो पंक्ति का एक नया संस्करण सम्मिलित करता है।

इन परिणामों की ओर ले जाने वाले शोध को अनुदान समझौते n° 318633 के तहत यूरोपीय संघ के सातवें फ्रेमवर्क प्रोग्राम (FP7/2007-2013) से धन प्राप्त हुआ है


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL 8.4 भूमिका के लिए सभी तालिकाओं पर DML विशेषाधिकार प्रदान करता है

  2. मैं PostgreSQL में कॉलम डिफ़ॉल्ट मान कैसे बदलूं?

  3. रेल 3.2 पोस्टग्रेज त्रुटि सहेजें ActiveRecord ::StatementInvalid:PG ::त्रुटि:त्रुटि:स्थिति 5 पर 'T' के पास सिंटैक्स त्रुटि

  4. ऑटो इंक्रीमेंट टेबल कॉलम

  5. पोस्टग्रेज:मानों के योग का चयन करें और फिर इसे फिर से जोड़ दें