sql >> Databasteknik >  >> RDS >> PostgreSQL

När är (SELECT) frågor planerade?

Jag kan inte prata om själva Perl-gränssnittet på klientsidan men jag kan kasta lite ljus över PostgreSQL-serversidan.

PostgreSQL har förberett uttalanden och oförberedda uttalanden. Oförberedda uttalanden analyseras, planeras och exekveras omedelbart. Det gör de också inte stödja parametersubstitution. På en vanlig psql shell kan du visa deras frågeplan så här:

tmpdb> explain select * from sometable where flag = true;

Å andra sidan finns det förberedda uttalanden:De är vanligtvis (se "undantag" nedan) analyserade och planerade i ett steg och exekveras i ett andra steg. De kan köras om flera gånger med olika parametrar, eftersom de gör stödja parametersubstitution. Motsvarigheten i psql är detta:

tmpdb> prepare foo as select * from sometable where flag = $1;
tmpdb> explain execute foo(true);

Du kanske ser att planen skiljer sig från planen i det oförberedda uttalandet, eftersom planering ägde rum redan i prepare fas enligt beskrivningen i dokumentet för FÖRBEREDA :

Detta betyder också att planen INTE är optimerad för de ersatta parametrarna:I de första exemplen kan ett index användas för flag eftersom PostgreSQL vet att inom en miljon poster bara tio har värdet true . Detta resonemang är omöjligt när PostgreSQL använder ett förberett uttalande. I så fall skapas en plan som kommer att fungera för alla möjliga parametervärden så bra som möjligt. Detta kan exkludera det nämnda indexet eftersom det går långsammare att hämta den bästa delen av hela tabellen via slumpmässig åtkomst (på grund av indexet) än en vanlig sekventiell genomsökning. PREPARE doc bekräftar detta:

BTW - Angående plancachning av PREPARE doc har också något att säga:

Det finns heller ingen automatisk plancachning och ingen cachning/återanvändning över flera anslutningar.

UNDANTAG :Jag har nämnt "vanligtvis". Den visade psql exempel är inte det som en klientadapter som Perl DBI verkligen använder. Den använder ett visst protokoll . Här motsvarar termen "enkel fråga" den "oförberedda frågan" i psql , termen "utökad fråga " motsvarar "prepared query" med ett undantag:Det finns en distinktion mellan (ett) "unnamed statement" och (eventuellt flera) "named statements". När det gäller namngivna uttalanden, är doc säger:

och även:

Så i det här fallet görs planering utan parametrar som beskrivs ovan för PREPARE - inget nytt.

Det nämnda undantaget är det "onamngivna uttalandet". Läkaren säger:

Och här är fördelen:Även om den icke namngivna satsen är "förberedd" (dvs. kan ha parametersubstitution), kan den också anpassa frågeplanen till de faktiska parametrarna.

BTW:Den exakta hanteringen av det namnlösa uttalandet har ändrats flera gånger i tidigare utgåvor av PostgreSQL-servern. Du kan slå upp de gamla dokumenten för detaljer om du verkligen vill.

Bakgrund – Perl / valfri klient :

Hur en klient som att Perl använder protokollet är en helt annan fråga. Vissa klienter som JDBC-drivrutinen för Java säger i princip:Även om programmeraren använder en förberedd sats, mappas de första fem (eller så) körningarna internt till en "enkel fråga" (dvs. i praktiken oförberedd), efter det växlar drivrutinen till " namngett uttalande".

Så en klient har dessa val:

  • Tvinga fram (om)planering varje gång genom att använda protokollet "enkel fråga".
  • Planera en gång, kör flera gånger genom att använda "extended query"-protokollet och "named statement" (planen kan vara dålig eftersom planering görs utan parametrar).
  • Parse en gång, planera för varje exekvering (med nuvarande PostgreSQL-version) genom att använda "extended query"-protokollet och "unnamed statement" och lyda några fler saker (ge några params under "parse"-meddelandet)
  • Spela helt andra trick som JDBC-drivrutinen.

Vad Perl gör för närvarande:Jag vet inte. Men den nämnda "rödströmmingen" är inte särskilt osannolik.




  1. Openshift och net-ssh inkompatibilitet? (2.9.3-beta1 mot 2.9.2)

  2. Oracle SQL grupp för kolumn med antal men bara om kolumnen är null eller 0

  3. Beräkna exakt månadsskillnad mellan två datum

  4. Förhindrar server-side scripting, XSS