2013-07-02 2 views
1

작동하지만 매우 느린 저장 프로 시저가 있습니다.subselect inPL/pgSQL에서 한 번에 여러 레코드를 업데이트하는 방법

기본적으로 내가하고 싶은 것은 하나의 업데이트 명령으로 하위 쿼리에서 얻은 행 집합을 업데이트하는 것입니다. 다른주의 사항은 명세서에서 업데이트 한 행을 반환하고 싶다는 것입니다.

지금 루프를 사용하여 하나의 행을 가져 와서 업데이트하고 결과를 저장하는 것으로 돌아가며 작동하지만 실제로 느립니다.

제안 사항?

다음은 스키마 작성 문과 함께 현재 작업중인 버전입니다.

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

이 쓰기 가능한 공통 테이블에 대한 좋은 후보처럼 보인다 표현 (wCTE). 그것은 PL/PgSQL입니다. PostgreSQL은 Oracle 절차 언어 PL/SQL을 지원하지 않습니다. –

답변

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) 
관련 문제