이 사이트에서 많은 도움을받은 후 필자는 원하는 작업을 수행하는 일련의 함수를 만들었습니다. 고마워요.하지만 마지막 문제는 효율적인 메모리 사용이라는 것 같습니다.
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.
질문 : 내가 원하는 테이블을 효과적으로 업데이트하거나 수정하려면 어떻게해야합니까? 어떤 아이디어?
미리 감사드립니다.
은 무엇 년대 쿼리가 "충돌"할 때 나타나는 메시지? PostgreSQL의 어떤 버전입니까? 충돌하는 업데이트를 수행하는 함수는 어디에 있습니까? – Kuberchaun
@JustBob 요청한 정보로 내 질문을 업데이트했습니다. 지금 나 한테 몇 가지 힌트를 줄 수 있니? –
테이블에 인덱스가 있습니까? DDL을 제공 할 수 있습니까? PostgreSQL은 32 비트 또는 64 비트 용으로 컴파일됩니다. 32 비트에서 이와 같은 문제가 있었던 사람들은 기억하지만, 64 비트에서는 잘 작동합니다. – Kuberchaun