2013-12-18 2 views
0

이 사이트에서 많은 도움을받은 후 필자는 원하는 작업을 수행하는 일련의 함수를 만들었습니다. 고마워요.하지만 마지막 문제는 효율적인 메모리 사용이라는 것 같습니다.
postgISSQL 9.3에서는 postGIS 2.1과 pgRouting 2.0을 사용하여 pgrouting 함수 pgr_trsp를 사용하여 2 점 사이의 경로를 계산하고 기하학 (선 스트링) 값을 반환하는 함수를 만들었습니다. 이 코드는 다음과 같습니다.PostgreSQL 함수 및 메모리 문제

CREATE OR REPLACE FUNCTION fm_pgr2geom(edge1 integer, pos1 double precision, edge2 integer, pos2 double precision) 
    RETURNS geometry AS 
$BODY$ 
--We have to do a routing query. And declare a cursor for it 
DECLARE resc CURSOR FOR 
SELECT * FROM pgr_trsp (
    'SELECT * FROM th_2po_4pgr', 
    $1, $2, $3, $4, false, true); 
doline geometry[]; 
temp_point geometry; 
geom geometry; 
temp_rec RECORD; 
n integer; 
BEGIN 

--Append all the edges 
FOR temp_rec IN SELECT * FROM pgr_trsp (
    'SELECT * FROM th_2po_4pgr', 
    $1, $2, $3, $4, false, true) LOOP 
     doline := array_append(
     doline, (SELECT map.geom_way FROM th_2po_4pgr map WHERE map.id = temp_rec.id2)); 
END LOOP; 
--Remove 1st and last edge 
n := array_length (doline, 1); 
doline := doline [2:n-1]; 
--Find startpoint and append to doline 
doline := array_prepend(
    ST_LineInterpolatePoint((SELECT map.geom_way FROM th_2po_4pgr map WHERE map.id = $1),$2),doline); 
--Append the endpoint 
doline := array_append(
    doline,ST_LineInterpolatePoint((SELECT map.geom_way FROM th_2po_4pgr map WHERE map.id = $3),$4)); 
geom := ST_MakeLine(doline); 
RETURN geom; 
EXCEPTION 
WHEN SQLSTATE 'XX000' THEN RETURN NULL; 
WHEN SQLSTATE '38001' THEN RETURN NULL; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION fm_pgr2geom(integer, double precision, integer, double precision) 
    OWNER TO postgres; 

이 함수는 다른 함수에서 크기가 큰 테이블 (800k +)을 배치 결과로 일괄 적으로 업데이트하는 데 사용됩니다. 여기 참조 용이다

CREATE OR REPLACE FUNCTION fm_seqrouting() 
    RETURNS integer AS 
$BODY$ 
--Declarations 
DECLARE 
    r record; 
    i integer; 
BEGIN 
--CODE to calculate routes and update table 
    i := 0; 
FOR r IN 
    SELECT veh_id 
     ,dt 
     ,map_edge_id    AS map_id1 
     ,map_edge_pos    AS map_pos1 
     ,lead(map_edge_id)  OVER w AS map_id2 
     ,lead(map_edge_pos)  OVER w AS map_pos2 
    FROM taxilocs 
    WINDOW w AS (ORDER BY veh_id, dt) 
    LOOP 

     UPDATE taxilocs 
      SET geom_route = fm_pgr2geom (r.map_id1,r.map_pos1,r.map_id2,r.map_pos2) 
      WHERE r.veh_id = taxilocs.veh_id AND r.dt=taxilocs.dt; 
     i := i + 1; 

    END LOOP; 
RETURN i; 
END; 
$BODY$ 
    LANGUAGE plpgsql; 

예외는 일부 데이터가 상기 테이블에없는 경우를 취급하기 때문에, 반드시 필요한, 또는 라우팅 경로를 찾을 수 없다. 그러나 몇 분 후에 업데이트 쿼리가 충돌한다는 문제를 일으키는 것으로 보입니다. 실행 시간이 몇 분 후에 수신되는 메시지는 다음과 같습니다.

ERROR: out of memory
SQL state: 53200
Detail: Failed on request of size 640000.

질문 : 내가 원하는 테이블을 효과적으로 업데이트하거나 수정하려면 어떻게해야합니까? 어떤 아이디어?
미리 감사드립니다.

+0

은 무엇 년대 쿼리가 "충돌"할 때 나타나는 메시지? PostgreSQL의 어떤 버전입니까? 충돌하는 업데이트를 수행하는 함수는 어디에 있습니까? – Kuberchaun

+0

@JustBob 요청한 정보로 내 질문을 업데이트했습니다. 지금 나 한테 몇 가지 힌트를 줄 수 있니? –

+0

테이블에 인덱스가 있습니까? DDL을 제공 할 수 있습니까? PostgreSQL은 32 비트 또는 64 비트 용으로 컴파일됩니다. 32 비트에서 이와 같은 문제가 있었던 사람들은 기억하지만, 64 비트에서는 잘 작동합니다. – Kuberchaun

답변

0

명령 아래 psql의를 사용하여 명령 줄에서 SQL을 실행하려고 -h < 호스트 이름> -d < DBNAME> -U < 사용자 이름> -p < 포트 이름> -f < 파일 이름>