postgresql Problem z uzyciem indeksu przez operator ANY

pyt Q

Witam,
Mam funkcje napisana w SQL w ktorej uzywam zapytania typu "WHERE column = ANY( $1)", gdzie $1 to integer[] (array).
Po analizie czasu jej wykonania (dlugi) sprawdzilem rozwiniecie tej funkcji jako zwykle zapytanie i wyszlo mi, ze indeks zalozony na "column" nie jest uzywany (seq scan na filter: column ANY({1,2,3}:integer[])). Kiedy zmienie konstrukcje na "WHERE column IN ( tutaj lista recznie wklejona)" to indeks jest uzywany i zapytanie jest szybsze. Ale IN nie akceptuje array jako argumentu ;(
Tak wiec moje pytania sa takie: 1. Czy mozna zoptymalizowac operator ANY lub zapytanie tak aby uzywany byl indeks (wydaje sie, ze nie powienien sie on roznic od IN) 2. W jaki inny sposob przekazac liste wartosci tak zeby uzyc jej w IN (albo jakos przeksztalcic wewnatrz funkcji array w liste akceptowalna przez IN) 3. Jak badac/analizowac plany zapytania dla funkcji (tzn. czy da sie jakos rozwinac analize zapytania w funkcji) - podejrzewam, ze nei ma sposobu, ale moze ;)
PS. Funkcja jest kilkuargumentowa, z czego 2 sa array, wiec odpada iterowanie po argumentach.

odp A

Witam,
Mam funkcje napisana w SQL w ktorej uzywam zapytania typu "WHERE column = ANY( $1)", gdzie $1 to integer[] (array).
Po analizie czasu jej wykonania (dlugi) sprawdzilem rozwiniecie tej funkcji jako zwykle zapytanie i wyszlo mi, ze indeks zalozony na "column" nie jest uzywany (seq scan na filter: column ANY({1,2,3}:integer[])).
ml wrote at -03-11 11:09:
postgresql 8.3.0:
CREATE TABLE fact(id bigserial primary key, data text); INSERT INTO fact select * from generate_series(1,00); ANALYZE fact; EXPLAIN ANALYZE SELECT * from fact where id = ANY ( ARRAY[1,2,3] ) ;
wynik na 8.3.0: QUERY PLAN ------------------------------------------------------------------------------------------------------------------- (actual time=0.052..0.053 rows=3 loops=1) Recheck Cond: (id = ANY ('{1,2,3}'::integer[])) -> Bitmap Index Scan on fact_pkey (cost=0.00..12.78 rows=3 width=0) (actual time=0.045..0.045 rows=3 loops=1) Index Cond: (id = ANY ('{1,2,3}'::integer[])) Total runtime: 0.097 ms (5 rows)
wynik na 8.2.4: QUERY PLAN ------------------------------------------------------------------------------------------------------------------- (actual time=0.047..0.048 rows=3 loops=1) Recheck Cond: (id = ANY ('{1,2,3}'::integer[])) -> Bitmap Index Scan on fact_pkey (cost=0.00..12.78 rows=3 width=0) (actual time=0.041..0.041 rows=3 loops=1) Index Cond: (id = ANY ('{1,2,3}'::integer[])) Total runtime: 0.089 ms (5 rows)
Time: 44.812 ms
jak widać używa indeksu.

> Kiedy zmienie konstrukcje na "WHERE column IN ( tutaj lista recznie > wklejona)" > to indeks jest uzywany i zapytanie jest szybsze. Ale IN nie akceptuje > array > jako argumentu ;( > > Tak wiec moje pytania sa takie: > 1. Czy mozna zoptymalizowac operator ANY lub zapytanie tak aby > uzywany byl indeks (wydaje sie, ze nie powienien sie on roznic od IN)
można i jak widać w 8.2 zostało to zronbione
> 2. W jaki inny sposob przekazac liste wartosci tak zeby uzyc jej w IN > (albo jakos > przeksztalcic wewnatrz funkcji array w liste akceptowalna przez IN)
dynamicznym sqlem (execute)
> 3. Jak badac/analizowac plany zapytania dla funkcji (tzn. czy da sie > jakos rozwinac analize > zapytania w funkcji) - podejrzewam, ze nei ma sposobu, ale moze ;)
możesz rozwinąć pytanie?

Dodaj odpowiedź

Tytuł:

Mail: (w celu weryfikacji posta)