У меня есть большая таблица меток времени в Postgres 9.4.5:
CREATE TABLE vessel_position (
posid serial NOT NULL,
mmsi integer NOT NULL,
"timestamp" timestamp with time zone,
the_geom geometry(PointZ,4326),
CONSTRAINT "PK_posid_mmsi" PRIMARY KEY (posid, mmsi)
);
Дополнительный индекс:
CREATE INDEX vessel_position_timestamp_idx ON vessel_position ("timestamp");
Я хочу извлечь каждую строку, где метка времени не меньше xминут после предыдущего ряда.Я пробовал несколько различных SELECT
операторов, используя LAG()
, которые все работали, но не дали мне точного результата, который мне нужен.Приведенные ниже функции дают мне то, что мне нужно, но я чувствую, что это может быть быстрее:
CREATE OR REPLACE FUNCTION _getVesslTrackWithInterval(mmsi integer, startTime character varying (25) ,endTime character varying (25), interval_min integer)
RETURNS SETOF vessel_position AS
$func$
DECLARE
count integer DEFAULT 0;
posids varchar DEFAULT '';
tbl CURSOR FOR
SELECT
posID
,EXTRACT(EPOCH FROM (timestamp - lag(timestamp) OVER (ORDER BY posid asc)))::int as diff
FROM vessel_position vp WHERE vp.mmsi = $1 AND vp.timestamp BETWEEN $2::timestamp AND $3::timestamp;
BEGIN
FOR row IN tbl
LOOP
count := coalesce(row.diff,0) + count;
IF count >= $4*60 OR count = 0 THEN
posids:= posids || row.posid || ',';
count:= 0;
END IF;
END LOOP;
RETURN QUERY EXECUTE 'SELECT * from vessel_position where posid in (' || TRIM(TRAILING ',' FROM posids) || ')';
END
$func$ LANGUAGE plpgsql;
Я не могу не думать, получая все posids
в виде строки, а затем снова выбирая их все в тот же самыйконец замедляет вещи.В операторе IF
у меня уже есть доступ к каждой строке, которую я хочу сохранить, поэтому потенциально могу сохранить их во временной таблице и затем вернуть временную таблицу в конце цикла.
Может ли эта функция бытьоптимизирован - для повышения производительности, в частности?