Możesz to osiągnąć za pomocą prostej funkcji SQL. Kluczową cechą jest funkcja 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;
Zadzwoń:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
Lub to samo z tablicą literal - co jest wygodniejsze w niektórych kontekstach, zwłaszcza przy przygotowanych wypowiedziach:
SELECT * FROM f_attendance('{{1,1},{2,2}}');
Funkcja zawsze oczekuje tablicy 2D. Nawet jeśli miniesz jedną parę, zagnieżdż ją:
SELECT * FROM f_attendance('{{1,1}}');
Audyt Twojej implementacji
-
Utworzyłeś funkcję
VOLATILE
, ale może byćSTABLE
. Zgodnie z dokumentacją:Z powodu tego zachowania migawkowego funkcja zawierająca tylko
SELECT
polecenia mogą być bezpiecznie oznaczone jakoSTABLE
.Powiązane:
- Jak przekazać parametr do funkcji daty
-
Możesz także użyć
LANGUAGE plpgsql
zamiastsql
, co ma sens, jeśli wykonujesz funkcję wiele razy w tej samej sesji. Ale musisz też ustawić goSTABLE
lub stracisz tę potencjalną korzyść w zakresie wydajności. Instrukcja jeszcze raz:STABLE
iIMMUTABLE
funkcje używają migawki utworzonej na początku zapytania wywołującego, podczas gdy funkcje VOLATILE uzyskują świeżą migawkę na początku każdego wykonywanego zapytania. -
Twój
EXPLAIN
dane wyjściowe pokazują Skanowanie tylko indeksu , a nie sekwencyjny skan, jak podejrzewasz w swoim komentarzu. -
Istnieje również krok sortowania w
EXPLAIN
dane wyjściowe, które nie pasują do kodu, który pokazujesz. Czy na pewno skopiowałeś właściwyEXPLAIN
? wyjście? Jak w ogóle go zdobyłeś? Funkcje PL/pgSQL to czarne skrzynki doEXPLAIN
. Czy użyłeśauto_explain
? ? Szczegóły:- Plan zapytań Postgres wywołania UDF napisany w pgpsql
-
Planer zapytań Postgres nie ma pojęcia, ile elementów tablicy będzie miał przekazany parametr, więc trudno jest zaplanować zapytanie i może domyślnie skanować sekwencyjnie (w zależności od większej liczby czynników). Możesz pomóc, deklarując oczekiwaną liczbę wierszy. Jeśli zazwyczaj nie masz więcej niż 10 pozycji, dodaj
ROWS 10
tak jak ja teraz powyżej. I przetestuj ponownie.