I have a table with about 300 columns and about 107 rows and I have to retrieve changed rows only, ordered by time (not distinct, but changed). The result set may be limited to 100 rows as well.
I've tried the following query with lag
window function:
-- Suppose, we want to retrieve data from column1, column2 and column3 fields
-- There may be other fields, though
SELECT
w."stamp",
w."column1",
w."column2",
w."column3"
FROM (
SELECT
o.stamp,
o.obj_id,
"o"."column1",
"o"."column2",
"o"."column3",
lag(o."column1") OVER (ORDER BY stamp) AS "_prev_column1",
lag(o."column2") OVER (ORDER BY stamp) AS "_prev_column2",
lag(o."column3") OVER (ORDER BY stamp) AS "_prev_column3"
FROM "table_name" o
WHERE o.stamp BETWEEN '01.12.2015 00:00' AND '23.01.2016 00:00'
ORDER BY o.stamp DESC
) AS w
WHERE
w.obj_id = 42 AND w.stamp BETWEEN '01.12.2015 00:00' AND '23.01.2016 00:00' AND
("w"."_prev_column_1", "w"."_prev_column_2", "w"."_prev_column_3") IS DISTINCT FROM
("w"."column_1", "w"."column_2", "w"."column_3")
ORDER BY w.stamp DESC
LIMIT 100;
However, it takes too much time to complete. Is it possible to optimize this query, or the problem should be solved in another way (e.g., custom function)?
Table definition:
CREATE TABLE table_name (
id BIGINT PRIMARY KEY NOT NULL DEFAULT nextval('ds_dyn_sequence'::regclass),
obj_id BIGINT NOT NULL,
stamp TIMESTAMP NOT NULL DEFAULT now(),
column1 BIGINT,
column2 BIGINT,
column3 BIGINT
-- Other fields, all BIGINT NULL
);
CREATE UNIQUE INDEX obj_id_stamp_key ON table_name USING BTREE (obj_id, stamp);
The table contains about 104 rows per a hour. The table will be limited to three months, so, the total number of rows will approximately be 2*107.
PostgreSQL version: 9.3