postgresql - 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 不能使用索引,因为在查询计划时参数值是未知的。
您可以使用动态生成的 SQL 语句而不是参数。
推荐阅读
- mongodb - Positional Projection 中的多个位置运算符
- python - 在某个点将列表分解为更小的列表
- python - 如何使用 python 在 Microsoft Graph 中显示用户的图像
- html - v-text-field 中的中心标签
- typescript - 如何告诉 TypeScript 我的函数参数是 Enum 键?
- javascript - 使用导致所有文档返回的 IN 子句时,Firebase 查询过滤器未定义
- shell - 交换目录 - shell - 使用 cp/mv
- c# - 来自 webclient C# 的空答案
- php - 我如何在 PDO 中使用 LIKE?
- android - 为轮廓提供者创建凸路径