数据库

pg_plan_filter:限制总成本


pg_plan_filter 是 Postgres 扩展,用于阻止执行查询计划器估计的总成本超过阈值的语句。 这旨在为数据库管理员提供一种限制单个查询对数据库负载的影响的方法。

启用扩展#

该扩展默认情况下已通过 shared_preload_libraries 设置启用。

您可以按照以下说明操作。

API#

plan_filter.statement_cost_limit:限制已执行语句的最大总成本 plan_filter.limit_select_only:限制为 select 语句

请注意,limit_select_only = true 与只读不同,因为 select 语句可以通过函数调用等方式修改数据。

示例#

为了演示总成本过滤,我们将比较 plan_filter.statement_cost_limit 如何处理低于其成本限制和高于其成本限制的查询。 首先,我们设置一个包含一些数据的表

1
create table book(
2
id int primary key
3
);
4
-- CREATE TABLE
5
6
insert into book(id) select * from generate_series(1, 10000);
7
-- INSERT 0 10000

接下来,我们可以查看单个记录选择和整个表选择的 explain 计划。

1
explain select * from book where id =1;
2
QUERY PLAN
3
---------------------------------------------------------------------------
4
Index Only Scan using book_pkey on book (cost=0.28..2.49 rows=1 width=4)
5
Index Cond: (id = 1)
6
(2 rows)
7
8
explain select * from book;
9
QUERY PLAN
10
---------------------------------------------------------
11
Seq Scan on book (cost=0.00..135.00 rows=10000 width=4)
12
(1 row)

现在我们可以选择一个 statement_cost_filter 值,介于单个选择的总成本(2.49)和整个表选择(135.0)之间,以便一个语句会成功,而另一个语句会失败。

1
set plan_filter.statement_cost_limit = 50; -- between 2.49 and 135.0
2
3
select * from book where id = 1;
4
id
5
----
6
1
7
(1 row)
8
-- SUCCESS
1
select * from book;
2
3
ERROR: plan cost limit exceeded
4
HINT: The plan for your query shows that it would probably have an excessive run time. This may be due to a logic error in the SQL, or it maybe just a very costly query. Rewrite your query or increase the configuration parameter "plan_filter.statement_cost_limit".
5
-- FAILURE

资源#