Jeg kan ikke tale om selve Perl-grænsefladen på klientsiden, men jeg kan kaste lidt lys over PostgreSQL-serversiden.
PostgreSQL har udarbejdet erklæringer og uforberedte erklæringer. Uforberedte udsagn analyseres, planlægges og udføres med det samme. Det gør de også ikke understøtte parametersubstitution. På en almindelig psql
shell kan du vise deres forespørgselsplan sådan her:
tmpdb> explain select * from sometable where flag = true;
På den anden side er der forberedte udsagn:De bliver normalt (se "undtagelse" nedenfor) parset og planlagt i ét trin og udført i et andet trin. De kan genudføres flere gange med forskellige parametre, fordi de gør understøtte parametersubstitution. Det tilsvarende i psql
er dette:
tmpdb> prepare foo as select * from sometable where flag = $1;
tmpdb> explain execute foo(true);
Du kan se, at planen er forskellig fra planen i den uforberedte erklæring, fordi planlægningen fandt sted allerede i prepare
fase som beskrevet i dokumentet for PREPARE
:
Dette betyder også, at planen IKKE er optimeret til de erstattede parametre:I de første eksempler kan der bruges et indeks for flag
fordi PostgreSQL ved, at inden for en million poster kun ti har værdien true
. Denne begrundelse er umulig, når PostgreSQL bruger en forberedt erklæring. I så fald oprettes en plan, som vil arbejde for alle mulige parameterværdier så godt som muligt. Dette måske udelukke det nævnte indeks, fordi det er langsommere at hente den bedste del af den komplette tabel via tilfældig adgang (på grund af indekset) end en almindelig sekventiel scanning. PREPARE
doc bekræfter dette:
BTW - Angående plancaching af PREPARE doc har også noget at sige:
Der er heller ingen automatisk plan-caching og ingen caching/genbrug over flere forbindelser.
UNDTAGELSE :Jeg har nævnt "normalt". Den viste psql
eksempler er ikke det, en klientadapter som Perl DBI virkelig bruger. Den bruger en bestemt protokol
. Her svarer udtrykket "simpel forespørgsel" til den "uforberedte forespørgsel" i psql
, udtrykket "udvidet forespørgsel " svarer til "forberedt forespørgsel" med én undtagelse:Der skelnes mellem (én) "unavngivet udsagn" og (muligvis flere) "navngivne udsagn". Med hensyn til navngivne udsagn er dok
siger:
og også:
Så i dette tilfælde udføres planlægning uden parametre som beskrevet ovenfor for PREPARE
- intet nyt.
Den nævnte undtagelse er den "unavngivne erklæring". Lægen siger:
Og her er fordelen:Selvom den unavngivne erklæring er "forberedt" (dvs. kan have parametersubstitution), kan den også tilpasse forespørgselsplanen til de faktiske parametre.
BTW:Den nøjagtige håndtering af den unavngivne erklæring har ændret sig flere gange i de tidligere udgivelser af PostgreSQL-serveren. Du kan slå de gamle dokumenter op for detaljer, hvis du virkelig vil.
Begrundelse - Perl / enhver klient :
Hvordan en klient ligesom Perl bruger protokollen er et helt andet spørgsmål. Nogle klienter som JDBC-driveren til Java siger grundlæggende:Selv hvis programmøren bruger en forberedt sætning, er de første fem (eller deromkring) udførelser internt afbildet til en "simpel forespørgsel" (dvs. faktisk uforberedt), hvorefter driveren skifter til " navngivne erklæring".
Så en klient har disse valgmuligheder:
- Tving (om)planlægning hver gang ved at bruge protokollen "simpel forespørgsel".
- Plan én gang, kør flere gange ved at bruge protokollen "udvidet forespørgsel" og den "navngivne sætning" (planen kan være dårlig, fordi planlægning udføres uden parametre).
- Parse én gang, planlæg for hver udførelse (med den aktuelle PostgreSQL-version) ved at bruge "udvidet forespørgsel"-protokollen og "unavngiven sætning" og adlyde nogle flere ting (giv nogle parametre under "parse"-meddelelsen)
- Spil helt andre tricks som JDBC-driveren.
Hvad Perl gør i øjeblikket:Jeg ved det ikke. Men den nævnte "røde sild" er ikke særlig usandsynlig.