我编写了非常简单的plpgsql函数,它从25mln行表中获取每一行并与prev行进行比较。如果两个兄弟行具有相等的"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_aoguid_not_unique扫描" Zemla" (成本= 0.56..3336281.02行= 25852488宽度= 37)"
答案 0 :(得分:1)
也许我误读了您的查询,但您不只是在识别在“Zemla”中出现多次的任何AOGUID条目吗?这不能作为单个分组查询完成吗?
SELECT "AOGUID" FROM "Zemla"
GROUP BY "AOGUID"
HAVING COUNT(*) > 1
ORDER BY "AOGUID"
答案 1 :(得分:0)
检查这种qry的费用:
explain with pre94 as (
SELECT "AOGUID", lag("AOGUID") over (ORDER BY "AOGUID") = "AOGUID" test_eq FROM "Zemla"
)
select "AOGUID" from pre94 where test_eq
我相信窗口功能可以帮助你完成比自己创建的功能更好的任务。
如果您使用9.4 or later
,也可以使用FILTER
减少qry