1
0
mirror of https://github.com/timescale/timescaledb.git synced 2025-05-20 04:35:00 +08:00
timescaledb/tsl/test/sql/include/modify_exclusion_load.sql
Sven Klemm ae50a53485 Add chunk exclusion for UPDATE for PG14
Currently only IMMUTABLE constraints will exclude chunks from an UPDATE plan,
with this patch STABLE expressions will be used to exclude chunks as well.
This is a big performance improvement as chunks not matching partitioning
column constraints don't have to be scanned for UPDATEs.
Since the codepath for UPDATE is different for PG < 14 this patch only adds
the optimization for PG14.

With this patch the plan for UPDATE on hypertables looks like this:

 Custom Scan (HypertableModify) (actual rows=0 loops=1)
   ->  Update on public.metrics_int2 (actual rows=0 loops=1)
         Update on public.metrics_int2 metrics_int2_1
         Update on _timescaledb_internal._hyper_1_1_chunk metrics_int2
         Update on _timescaledb_internal._hyper_1_2_chunk metrics_int2
         Update on _timescaledb_internal._hyper_1_3_chunk metrics_int2
         ->  Custom Scan (ChunkAppend) on public.metrics_int2 (actual rows=0 loops=1)
               Output: '123'::text, metrics_int2.tableoid, metrics_int2.ctid
               Startup Exclusion: true
               Runtime Exclusion: false
               Chunks excluded during startup: 3
               ->  Seq Scan on public.metrics_int2 metrics_int2_1 (actual rows=0 loops=1)
                     Output: metrics_int2_1.tableoid, metrics_int2_1.ctid
                     Filter: (metrics_int2_1."time" = length(version()))
2022-04-06 12:41:14 +02:00

82 lines
4.0 KiB
PL/PgSQL

-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
CREATE TABLE metrics_int2(c1 int,c2 int, c3 int, c4 int, c5 int, time int2 NOT NULL, value float, data text);
CREATE TABLE metrics_int4(c1 int,c2 int, c3 int, c4 int, c5 int, time int4 NOT NULL, value float, data text);
CREATE TABLE metrics_int8(c1 int,c2 int, c3 int, c4 int, c5 int, time int8 NOT NULL, value float, data text);
CREATE TABLE metrics_date(c1 int,c2 int, c3 int, c4 int, c5 int, time date NOT NULL, value float, data text);
CREATE TABLE metrics_timestamp(c1 int,c2 int, c3 int, c4 int, c5 int, time timestamp NOT NULL, value float, data text);
CREATE TABLE metrics_timestamptz(c1 int,c2 int, c3 int, c4 int, c5 int, time timestamptz NOT NULL, value float, data text);
CREATE TABLE metrics_space(c1 int,c2 int, c3 int, c4 int, c5 int, time timestamp NOT NULL, device text, value float, data text);
SELECT table_name FROM create_hypertable('metrics_int2','time',chunk_time_interval:=10);
SELECT table_name FROM create_hypertable('metrics_int4','time',chunk_time_interval:=10);
SELECT table_name FROM create_hypertable('metrics_int8','time',chunk_time_interval:=10);
SELECT table_name FROM create_hypertable('metrics_date','time');
SELECT table_name FROM create_hypertable('metrics_timestamp','time');
SELECT table_name FROM create_hypertable('metrics_timestamptz','time');
SELECT table_name FROM create_hypertable('metrics_space','time','device',4);
CREATE FUNCTION drop_column(text) RETURNS VOID LANGUAGE PLPGSQL AS $$
DECLARE
tbl name;
BEGIN
FOR tbl IN SELECT 'metrics_' || unnest(ARRAY['int2','int4','int8','date','timestamp','timestamptz','space'])
LOOP
EXECUTE format('ALTER TABLE %I DROP COLUMN %I;', tbl, $1);
END LOOP;
END;
$$;
-- create 4 chunks each with different physical layout
SELECT drop_column('c1');
INSERT INTO metrics_int2(time) VALUES (0);
INSERT INTO metrics_int4(time) VALUES (0);
INSERT INTO metrics_int8(time) VALUES (0);
INSERT INTO metrics_date(time) VALUES ('2000-01-01');
INSERT INTO metrics_timestamp(time) VALUES ('2000-01-01');
INSERT INTO metrics_timestamptz(time) VALUES ('2000-01-01');
INSERT INTO metrics_space(time,device) VALUES ('2000-01-01','1'),('2000-01-01','2');
SELECT drop_column('c2');
INSERT INTO metrics_int2(time) VALUES (10);
INSERT INTO metrics_int4(time) VALUES (10);
INSERT INTO metrics_int8(time) VALUES (10);
INSERT INTO metrics_date(time) VALUES ('2001-01-01');
INSERT INTO metrics_timestamp(time) VALUES ('2001-01-01');
INSERT INTO metrics_timestamptz(time) VALUES ('2001-01-01');
INSERT INTO metrics_space(time,device) VALUES ('2001-01-01','1'),('2001-01-01','2');
SELECT drop_column('c3');
INSERT INTO metrics_int2(time) VALUES (20);
INSERT INTO metrics_int4(time) VALUES (20);
INSERT INTO metrics_int8(time) VALUES (20);
INSERT INTO metrics_date(time) VALUES ('2002-01-01');
INSERT INTO metrics_timestamp(time) VALUES ('2002-01-01');
INSERT INTO metrics_timestamptz(time) VALUES ('2002-01-01');
INSERT INTO metrics_space(time,device) VALUES ('2002-01-01','1'),('2002-01-01','2');
SELECT drop_column('c4');
INSERT INTO metrics_int2(time) VALUES (30);
INSERT INTO metrics_int4(time) VALUES (30);
INSERT INTO metrics_int8(time) VALUES (30);
INSERT INTO metrics_date(time) VALUES ('2003-01-01');
INSERT INTO metrics_timestamp(time) VALUES ('2003-01-01');
INSERT INTO metrics_timestamptz(time) VALUES ('2003-01-01');
INSERT INTO metrics_space(time,device) VALUES ('2003-01-01','1'),('2003-01-01','2');
SELECT drop_column('c5');
CREATE TABLE metrics_compressed(time timestamptz NOT NULL, device int, value float);
SELECT table_name FROM create_hypertable('metrics_compressed','time');
ALTER TABLE metrics_compressed SET (timescaledb.compress);
-- create first chunk and compress
INSERT INTO metrics_compressed VALUES ('2000-01-01',1,0.5);
SELECT count(compress_chunk(chunk)) FROM show_chunks('metrics_compressed') chunk;
-- create more chunks
INSERT INTO metrics_compressed VALUES ('2010-01-01',1,0.5),('2011-01-01',1,0.5),('2012-01-01',1,0.5);