PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Przekaż wiele zestawów lub tablic wartości do funkcji

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

  1. 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 jako STABLE .

    Powiązane:

    • Jak przekazać parametr do funkcji daty
  2. Możesz także użyć LANGUAGE plpgsql zamiast sql , co ma sens, jeśli wykonujesz funkcję wiele razy w tej samej sesji. Ale musisz też ustawić go STABLE lub stracisz tę potencjalną korzyść w zakresie wydajności. Instrukcja jeszcze raz:

    STABLE i IMMUTABLE 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.

  3. Twój EXPLAIN dane wyjściowe pokazują Skanowanie tylko indeksu , a nie sekwencyjny skan, jak podejrzewasz w swoim komentarzu.

  4. 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ściwy EXPLAIN? wyjście? Jak w ogóle go zdobyłeś? Funkcje PL/pgSQL to czarne skrzynki do EXPLAIN . Czy użyłeś auto_explain? ? Szczegóły:

    • Plan zapytań Postgres wywołania UDF napisany w pgpsql
  5. 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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dzięki sqlalchemy, jak dynamicznie łączyć się z silnikiem bazy danych na podstawie żądania

  2. UUID czy SEQUENCE dla klucza podstawowego?

  3. Wartość błędu nie istnieje - postgresql INSERT INTO

  4. Uzyskaj rozmiar wszystkich baz danych w PostgreSQL (psql)

  5. baza danych zmiany nazwy postgres nie działa