由于Postgres似乎没有每个UDF(SQL Server does)具有多个结果集的功能。返回查询范围单例值的最佳方法是什么?例如,当对FTS搜索的结果进行分页时,如果我们可以获得与查询匹配的结果量,则可以简化逻辑(无需使用分页迭代所有页面)。
方法一:将post_count粘贴在SELECT列表中。缺点:重复
方法二:编写一个单独的UDF来获取post_count cons:多个UDF调用(我使用这种方法,它使得能够呈现第一页的延迟加倍)。
方法三:对结果集使用数组,并将post_count放在顶层作为结果集缺点的兄弟:慢得多 - 这可能是由于{{1}函数(是的,我试过这种方法)。
对于这个问题,是否有一个更实用的解决方案,如果没有,那么开发流程中是否还有什么可以解决这个问题呢?
答案 0 :(得分:1)
我自己反复遇到这个问题,但没有找到一个解决方案。
我的最新方法是将返回的SET的 第一行行定义为元数据。您的方法列表中没有那一行。 该应用程序使用第一行进行簿记。实际数据从第二行开始。
明显的弱点:你必须处理你必须在元数据中挤压的任何行定义。但是,简单的总计数将适合任何数字或字符串类型 当然,你必须特殊情况下应用程序的第一行。
这个简单的示例返回定义为
的表foo
中的行
CREATE TABLE foo (
foo_id serial PRIMARY KEY
,foo text
);
页面大小为20行,默认情况下在函数头中预先设置:
CREATE OR REPLACE FUNCTION f_paginate(_max_id int, _limit int = 20
, _offset int = 0)
RETURNS TABLE(foo_id int, foo text) AS
$BODY$
BEGIN
SELECT INTO foo_id count(*)::int
FROM foo f
WHERE f.foo_id < _max_id; -- get count
RETURN NEXT; -- use first row for meta-data
RETURN QUERY -- actual data starts with second row
SELECT f.foo_id, f.foo
FROM foo f
WHERE f.foo_id < _max_id
LIMIT _limit
OFFSET _offset;
END;
$BODY$
LANGUAGE plpgsql;
呼叫:
SELECT * FROM f_paginate(100);
返回:
foo_id | foo
-------+----
86 | <NULL> <-- first row = meta-data
1 | bar <-- actual data
2 | baz
... 18 more ...
显然,这种方法可以通过更高的_limit(页面大小)来节省一些带宽。只有几行,几乎不值得开销。
另一种方法是“方法一” - 冗余地添加一列:
CREATE OR REPLACE FUNCTION f_paginate2(_max_id int, _limit int = 20
, _offset int = 0)
RETURNS TABLE(foo_id int, foo text, ct bigint) AS
$BODY$
BEGIN
RETURN QUERY
SELECT f.foo_id, f.foo, count(*) OVER ()
FROM foo f
WHERE f.foo_id < _max_id
LIMIT _limit
OFFSET _offset;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
呼叫:
SELECT * FROM f_paginate2(100);
返回:
foo_id | foo | ct
-------+-----+----
1 | bar | 86
2 | baz | 86
... 18 more ...
在这个简单的案例中,表现非常相似。第一个查询稍快,但可能只是因为count(*) OVER ()
减慢了第二个查询的速度。仅count(*)
的单独运行速度更快。