2

Having a index:

CREATE INDEX foo_idx ON my_table(name, value) WHERE deleted_by_request_id IS NULL AND name IN ('a', 'b');

Tables properties:

SELECT COUNT(*) FROM my_table => 76.560.014
SELECT COUNT(*) FROM my_table WHERE deleted_by_request_id IS NULL AND name = 'a' => 3.190.001
SELECT COUNT(*) FROM my_table WHERE deleted_by_request_id IS NULL AND name = 'b' => 3.190.001

When running:

SELECT id FROM my_table WHERE deleted_by_request_id IS NULL AND name = 'a' AND value = 'bla'

it takes 14msec

Now i put the query in a function:

CREATE OR REPLACE FUNCTION my_func(param_value VARCHAR(4000))
  RETURNS TABLE (id INTEGER)
  LANGUAGE SQL
AS $$
  SELECT id FROM my_table WHERE deleted_by_request_id IS NULL AND name = 'a' AND value = param_value
$$;

Still 14msec

 CREATE OR REPLACE FUNCTION my_func(param_name VARCHAR(4000), param_value VARCHAR(4000))
  RETURNS TABLE (id INTEGER)
  LANGUAGE SQL
AS $$
  SELECT id FROM my_table WHERE deleted_by_request_id IS NULL AND name = param_name AND value = param_value
$$;

Calling it with SELECT my_func('a', 'bla')

30 seconds

Any ideas?

PostgreSQL 12.4 (Debian 12.4-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit

1 Answer 1

2

PostgreSQL does not use the index, because the parameter value is not known at query planning time.

You could use a dynamically generated SQL statement rather than parameters.

Sign up to request clarification or add additional context in comments.

2 Comments

Thx a lot - with RETURN QUERY EXECUTE ... USING it works!!
I think this should read "PostgreSQL does not use the index" instead of "PostgreSQL cannot use the index", because Postgres absolutely can. It's just that for a generic value, the best generic plan may be not to use an index, where it would make sense to use one, if we had known the value (and column statistics derived from it). Another question linking here got mislead by "cannot".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.