带有函数wrap sql的postgresql这么慢?

Posted

技术标签:

【中文标题】带有函数wrap sql的postgresql这么慢?【英文标题】:postgresql with function wrap sql so slow? 【发布时间】:2018-11-12 10:15:55 【问题描述】:

第一个sql解释分析:

explain  analyse  select * from ttq.ttq_post;
Seq Scan on ttq_post  (cost=10000000000.00..10000000014.71 rows=171 width=547) (actual time=0.005..0.027 rows=176 loops=1)
Planning Time: 0.033 ms
Execution Time: 0.041 ms

但是如果使用函数包装相同的sql 例如:

create or replace function ttq.test_fn_slow() 
  returns  setof ttq.ttq_post 
  language  sql 
  stable 
as $$
select * from ttq.ttq_post;
$$

和执行打击功能:

explain  analyse  select ttq.test_fn_slow();

结果:

ProjectSet  (cost=0.00..5.27 rows=1000 width=32) (actual time=0.063..0.175 rows=176 loops=1)
  ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
Planning Time: 0.013 ms
Execution Time: 0.192 ms

为什么使用函数换行这么慢?

尝试用“immutable”替换“stable”,结果还是一样!

【问题讨论】:

我会说差异是随机的。多试几次,看看你是否真的能观察到持久的显着性能差异。用更大的表进行测试也可能很好。 谢谢你的回答,我执行这个命令几次,结果没有区别第一个 sql 花费时间大约 0.040ms,函数花费时间大约 0.19ms。相同的sql,为什么花费时间不同? 运行SELECT * FROM ttq.test_fn_slow();是不是也一样? if exec SELECT * FROM ttq.test_fn_slow();花费时间与单个 sql 相同(从 ttq.ttq_post 中选择 *)!! select * from functionName() 和 select functionName() 有区别吗? 【参考方案1】:

额外的成本一定是由于您在SELECT 子句而不是FROM 子句中使用了集合返回函数。

请注意,在 PostgreSQL v10 中,SELECT 子句中对集合返回函数的处理发生了变化,因此您的版本可能会影响此行为。

【讨论】:

谢谢你的回答,如果我想返回一个选择结果如何编写函数? 只从functionName()中选择propName ? 是的。我相信你必须为函数添加一个表别名。

以上是关于带有函数wrap sql的postgresql这么慢?的主要内容,如果未能解决你的问题,请参考以下文章

在 PostgreSQL 数据库中插入带有 jOOQ 的 SQL 枚举

PostgreSQL:查询在带有变量的查询中没有结果数据的目的地

带有 pg8000 的 PostgreSQL - 从 SQL 插入结果到另一个表

带有重试行为的 Go sql 包、PostgreSQL 和 PgBouncer

带有spring boot JPA Postgresql的data.sql未加载

带有可选参数的 Postgresql 函数