首页 > 解决方案 > PostgreSQL 在通过参数传递时不使用索引

问题描述

有一个索引:

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

表属性:

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

运行时:

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

需要 14 毫秒

现在我把查询放在一个函数中:

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
$$;

仍然是 14 毫秒

 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
$$;

用 SELECT my_func('a', 'bla') 调用它

30秒

有任何想法吗?

x86_64-pc-linux-gnu 上的 PostgreSQL 12.4 (Debian 12.4-1.pgdg100+1),由 gcc (Debian 8.3.0-6) 8.3.0 编译,64 位

标签: postgresql

解决方案


PostgreSQL 不能使用索引,因为在查询计划时参数值是未知的。

您可以使用动态生成的 SQL 语句而不是参数。


推荐阅读