sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL-mod:Vad är "resjunk"?

Jag fördjupar mig i PostgreSQL-parsern, frågeomskrivaren och frågeplaneraren för tillfället, som en del av arbetet med säkerhet på radnivå för AXLE-projektet. Eftersom jag har märkt att det finns en del bra dokumentation om den övergripande strukturen och flödet men inte mycket om några av detaljerna tänkte jag att jag skulle börja skriva om några av de mer förvirrande hörnen.

Om du inte är intresserad av PostgreSQL-källkoden och dess inre funktioner kan du sluta läsa nu.

återskräp

Dagens ämne är termen "resjunk", som syftar på resjunk mållista-attribut. Du kommer att se denna term genom hela planeraren och omskrivaren, vanligtvis som antagen kunskap. Namnet är inte särskilt användbart.

resjunk kolumner beskrivs i src/backend/executor/execJunk.c , där det finns en måttligt detaljerad kommentar. Det förklarar dock inte riktigt de övergripande idéerna.

konceptet är att PostgreSQL ibland behöver hålla reda på per-tupelinformation som inte är en del av frågeutmatningen. Det kan vara en sorteringsnyckel som inte ingår i urvalslistan, ett mellanresultat från en underfråga som används som ett filter och sedan kasseras, eller det kan vara en intern kolumn som ctid som inte exponeras för användare.

Plannoder har mållistor – dessa är listor med kolumner som matas ut av den plannoden. För ett enkelt VÄLJ a, b FRÅN-test kolumnerna a och b kommer att visas i mållistan för index- eller seqscan-plannoden för frågan. Du kan observera detta själv genom att aktivera planloggning, enligt följande trimmade utdata:

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

Det är den detaljerade planen för:

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

I den kommer du att se att SELECT har två poster i mållistan, en för varje kolumn. Inte heller resjunk eftersom båda matas ut av frågan.

Vad händer om vi lägger till en sortering efter kolumn c , som inte finns i SELECT -list kommer vi att se en ny kolumn läggas till i mållistan och markeras som 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)
      }
   )
   ....
   }

för frågeplanen:

                          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 är markerad med resjunk eftersom det är en sorteringsnyckel som inte är en del av den slutliga planen.

Du kommer också att se ctid markerad resjunk i UPPDATERING och RADERA planer av liknande skäl – den lästa delen av planen hämtar raderna som ska ändras och deras tupel-ID; dessa dras in i en yttersta ÄNDRINGSTABELL plannod som uppdaterar raden för att markera den som borttagen och, om det är en uppdatering, infogar en ny version av raden.

Den forskning som leder till dessa resultat har fått finansiering från Europeiska unionens sjunde ramprogram (FP7/2007-2013) under bidragsavtal nr 318633


  1. Hur man dokumenterar en databas

  2. Hur deklarerar man indata-utgångsparametrar i lagrad procedur/funktion i SQL Server?

  3. php-kod för att testa pdo är tillgänglig?

  4. MySQL - ORDER BY-värden inom IN()