【发布时间】:2017-03-14 11:18:31
【问题描述】:
我编写了非常简单的 plpgsql 函数,它从 2500 万行表中获取每一行并与上一行进行比较。如果两个同级行具有相等的"AOGUID" 列,则返回它们。
CREATE or replace FUNCTION get_duplicate_zemli() RETURNS setof character varying AS $$
DECLARE
each_zemla character varying;
prev_zemla character varying;
BEGIN
FOR each_zemla IN SELECT "AOGUID" FROM "Zemla" ORDER BY "AOGUID" LOOP
if (prev_zemla = each_zemla) then
return next each_zemla;
end if;
prev_zemla:= each_zemla;
END LOOP;
END;
$$ LANGUAGE plpgsql;
据我了解,这个函数应该在接近普通查询时间的时候执行
SELECT "AOGUID" FROM "Zemla" ORDER BY "AOGUID"
不幸的是,这不是真的。普通查询在一小时内执行,而函数在 80 小时内执行!
谁能解释一下为什么 plpgsql 函数的执行速度比普通查询慢得多,以及如何提高性能?
PS:
explain SELECT "AOGUID" FROM "Zemla" ORDER BY "AOGUID"
“在“Zemla”上使用 zemla_aoguid_not_unique 进行仅索引扫描 (成本=0.56..3336281.02 行=25852488 宽度=37)"
【问题讨论】:
-
不相关,但是 - 为什么不使用窗口函数?例如
lag或lead?... -
如果你可以使用纯 SQL 的话,永远不要使用 for 循环(或 PL/pgSQL)。
-
@a_horse_with_no_name: Never say never. 这个经验法则有例外。
-
有多种方法可以使这个(很多)更快。最佳答案取决于 [postgresql-performance] 问题的基本信息。请考虑instructions in the tag info. 最重要的是:您的Postgres 版本以及
"AOGUID"中有多少不同的值。 edit 问题中的所有定义信息,不要将其隐藏在 cmets 中。除此之外,basic 的 80 倍执行时间很奇怪。 -
您是要提供更多信息还是这个问题已经完成?
标签: performance postgresql plpgsql postgresql-performance