我有一个存储过程可行,但速度非常慢。
基本上我想要做的是在单个更新命令中更新从子查询中获得的一组行。另一个需要注意的是,我想返回我在语句中更新的行。
现在我正在使用一个循环获取单行并更新它,使用返回存储结果,这可以工作,但实际上很慢。
建议?
以下是当前工作版本以及架构创建语句。
CREATE TABLE "queued_message"
(
id bigserial NOT NULL,
body json NOT NULL,
status character varying(50) NOT NULL,
queue character varying(150) NOT NULL,
last_modified timestamp without time zone NOT NULL,
CONSTRAINT id_pkey PRIMARY KEY (id)
);
CREATE TYPE returned_message as (id bigint, body json, status character varying(50) , queue character varying(150), last_modified timestamp without time zone);
CREATE OR REPLACE FUNCTION get_next_notification_message_batch(desiredQueue character varying(150), numberOfItems integer)
RETURNS SETOF returned_message AS $$
DECLARE result returned_message; messageCount integer := 1;
BEGIN
lock table queued_notification_message in exclusive mode;
LOOP
update queued_notification_message
set
status='IN_PROGRESS', last_modified=now()
where
id in (
select
id
from
queued_notification_message
where
status='SUBMITTED' and queue=desiredQueue
limit 1
)
returning * into result;
RETURN NEXT result;
messageCount := messageCount+1;
EXIT WHEN messageCount > numberOfItems;
END LOOP;
END;$$LANGUAGE plpgsql;
答案 0 :(得分:0)
很难加速代码,因为UPDATE语句不支持的LIMIT子句也是如此,可能以下示例就足够了:
CREATE OR REPLACE FUNCTION public.fx2(n integer) RETURNS SETOF oo LANGUAGE plpgsql AS $function$ begin return query update oo set a = b where b in (select b from oo order by b limit n) returning *; return; end; $function$ postgres=# insert into oo select 1, i from generate_series(1,100) g(i); INSERT 0 100 postgres=# select * from fx2(1); a | b ---+--- 1 | 1 (1 row) postgres=# select * from fx2(4); a | b ---+--- 1 | 1 2 | 2 3 | 3 4 | 4 (4 rows) postgres=# select * from oo limit 10; a | b ---+---- 1 | 5 1 | 6 1 | 7 1 | 8 1 | 9 1 | 10 1 | 11 1 | 12 1 | 13 1 | 14 (10 rows)