2013-12-18 85 views
0

在從本網站收到很多幫助後,我終於創建了一套完成我想要的工作的功能。謝謝你,但似乎有一個最後的問題,即高效的內存使用情況。這裏是問題:
在postgreSQL 9.3中,使用postGIS 2.1和pgRouting 2.0,我創建了一個函數,它使用pgrouting函數pgr_trsp計算兩點之間的路線並返回一個幾何(Linestring)值。這裏是代碼: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位編譯的。我記得過去在32bit上有這樣的問題的人,但在64bit上工作正常。 – Kuberchaun

回答

0

嘗試運行在命令行中使用的SQL命令如下 的psql -h <主機名> -d < DBNAME> -U <用戶名> -p < PORTNAME> -f <文件名>