Dat bereik je met een simpele SQL-functie. Belangrijkste kenmerk is de functie generate_subscripts()
:
CREATE OR REPLACE FUNCTION f_attendance(_arr2d int[])
RETURNS SETOF attendance AS
$func$
SELECT a.*
FROM generate_subscripts($1, 1) i
JOIN attendance a ON a.class = $1[i][1]
AND a.section = $1[i][2]
$func$ LANGUAGE ROWS 10 sql STABLE;
Bel:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
Of hetzelfde met een array letterlijk - wat handiger is in sommige contexten, vooral met voorbereide verklaringen:
SELECT * FROM f_attendance('{{1,1},{2,2}}');
De functie altijd verwacht een 2D-array. Zelfs als je een enkel paar doorgeeft, nest het dan:
SELECT * FROM f_attendance('{{1,1}}');
Controle van uw implementatie
-
Je hebt de functie
VOLATILE
. gemaakt , maar het kanSTABLE
. zijn . Per documentatie:Vanwege dit snapshotgedrag is een functie die alleen
SELECT
. bevat commando's kunnen veilig worden gemarkeerd alsSTABLE
.Gerelateerd:
- Een parameter doorgeven aan een datumfunctie
-
Je gebruikt ook
LANGUAGE plpgsql
in plaats vansql
, wat logisch is als u de functie meerdere keren in dezelfde sessie uitvoert. Maar dan moet je het ookSTABLE
maken of u verliest dat potentiële prestatievoordeel. Nogmaals de handleiding:STABLE
enIMMUTABLE
functies gebruiken een momentopname die is gemaakt vanaf het begin van de aanroepende query, terwijl VOLATILE-functies een verse momentopname krijgen aan het begin van elke query die ze uitvoeren. -
Uw
EXPLAIN
uitvoer toont een Alleen Index Scan , geen sequentiële scan zoals je vermoedt in je opmerking. -
Er is ook een sorteerstap in uw
EXPLAIN
uitvoer die niet overeenkomt met de code die u laat zien. Weet je zeker dat je de juisteEXPLAIN
. hebt gekopieerd uitvoer? Hoe heb je die trouwens gekregen? PL/pgSQL-functies zijn zwarte dozen omEXPLAIN
. Heb jeauto_explain
. gebruikt? ? Details:- Postgres-queryplan van een UDF-aanroep geschreven in pgpsql
-
De queryplanner van Postgres heeft geen idee hoeveel array-elementen de doorgegeven parameter zal hebben, dus het is moeilijk om de query te plannen en kan standaard een sequentiële scan uitvoeren (afhankelijk van meer factoren). U kunt helpen door het verwachte aantal rijen aan te geven. Als u doorgaans niet meer dan 10 items heeft, voegt u
ROWS 10
toe toe zoals ik nu hierboven deed. En test opnieuw.