Функции PostgreSQL и проблемы с памятью

После получения большой помощи с этого сайта я наконец-то создал набор функций, которые выполняют ту работу, которую я хотел. Спасибо за это, но, похоже, есть еще одна проблема - эффективное использование памяти. Вот проблема:
В postgreSQL 9.3, используя postGIS 2.1 и pgRouting 2.0, я создал функцию, которая вычисляет маршрут между двумя точками, используя функцию pgrouting pgr_trsp, и возвращает значение геометрии (Linestring). Вот код:

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;  

Исключения являются абсолютно необходимыми, поскольку они обрабатывают некоторые случаи, когда некоторые данные отсутствуют в вышеупомянутой таблице или маршрут маршрутизации не может быть найден. Тем не менее, кажется, что они вызывают проблему, которая заключается в том, что запрос на обновление завершается через несколько минут. Сообщение, которое я получаю после нескольких минут выполнения:

ОШИБКА: недостаточно памяти
Состояние SQL: 53200
Деталь: Не удалось по запросу размером 640000.

Итак, вопрос: как я могу эффективно использовать или перекодировать эту функцию для обновления таблицы, которую я хочу? Есть идеи?
Заранее спасибо!

1 ответ

Попробуйте запустить sql из командной строки, используя следующую команду: psql -h -d -U -p -f

Другие вопросы по тегам