From fbc41600a328e78c3f2c3778413fa87231f5dbc3 Mon Sep 17 00:00:00 2001 From: Konstantina Skovola Date: Tue, 11 Apr 2023 12:33:11 +0300 Subject: [PATCH] Enable indexscan on uncompressed part of partially compressed chunks This was previously disabled as no data resided on the uncompressed chunk once it was compressed, but this is not the case anymore with partially compressed chunks, so we enable indexscan for the uncompressed chunk again. Fixes #5432 Co-authored-by: Ante Kresic (cherry picked from commit 5633960f8b0e4675e342b1721bde954fdbe938e7) --- CHANGELOG.md | 1 + src/planner/planner.c | 9 +- tsl/test/expected/compression_ddl.out | 395 ++++++++++++++++++++++++++ tsl/test/sql/compression_ddl.sql | 211 ++++++++++++++ 4 files changed, 613 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae56e619291..16c719bc294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ accidentally triggering the load of a previous DB version.** * #5462 Fix segfault after column drop on compressed table * #5543 Copy scheduled_jobs list before sorting it * #5497 Allow named time_bucket arguments in Cagg definition +* #5542 Enable indexscan on uncompressed part of partially compressed chunks **Thanks** * @nikolaps for reporting an issue with the COPY fetcher diff --git a/src/planner/planner.c b/src/planner/planner.c index ae45ae2cec0..f86d16648cc 100644 --- a/src/planner/planner.c +++ b/src/planner/planner.c @@ -1302,13 +1302,16 @@ timescaledb_get_relation_info_hook(PlannerInfo *root, Oid relation_objectid, boo ts_get_private_reloptinfo(rel)->compressed = true; - /* Planning indexes are expensive, and if this is a compressed chunk, we + /* Planning indexes is expensive, and if this is a fully compressed chunk, we * know we'll never need to use indexes on the uncompressed version, since * all the data is in the compressed chunk anyway. Therefore, it is much * faster if we simply trash the indexlist here and never plan any useless - * IndexPaths at all + * IndexPaths at all. + * If the chunk is partially compressed, then we should enable indexScan + * on the uncompressed part. */ - rel->indexlist = NIL; + if (!ts_chunk_is_partial(chunk)) + rel->indexlist = NIL; /* Relation size estimates are messed up on compressed chunks due to there * being no actual pages for the table in the storage manager. diff --git a/tsl/test/expected/compression_ddl.out b/tsl/test/expected/compression_ddl.out index f7a9ffcd05b..0f281b0877d 100644 --- a/tsl/test/expected/compression_ddl.out +++ b/tsl/test/expected/compression_ddl.out @@ -1337,3 +1337,398 @@ ALTER MATERIALIZED VIEW test1_cont_view2 SET ( timescaledb.compress = false ); DROP TABLE metric CASCADE; + +ALTER TABLE compression_insert SET (timescaledb.compress, timescaledb.compress_orderby='time DESC', timescaledb.compress_segmentby='device_id'); +-- test without altering physical layout +-- this is a baseline test to compare results with +-- next series of tests which should yield identical results +-- while changing the physical layouts of chunks +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-03 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id and ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-04 0:00:00+0'::timestamptz,'2000-01-05 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-01 0:00:00+0' +AND time <= '2000-01-05 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +-- force index scans to check index mapping +-- this verifies that we are actually using compressed chunk index scans +-- previously we could not use indexes on uncompressed chunks due to a bug: +-- https://github.com/timescale/timescaledb/issues/5432 +-- +-- this check basically makes sure that the indexes are built properly +-- and there are no issues in attribute mappings while building them +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + HashAggregate + Group Key: _hyper_31_107_chunk.device_id + -> Append + -> Custom Scan (DecompressChunk) on _hyper_31_107_chunk + -> Index Scan using compress_hyper_32_108_chunk__compressed_hypertable_32_device_id on compress_hyper_32_108_chunk + -> Index Only Scan using _hyper_31_107_chunk_compression_insert_device_id_time_idx on _hyper_31_107_chunk +(6 rows) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 3596 + 5 | 3596 + 4 | 3596 + 2 | 3596 + 1 | 3596 +(5 rows) + +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-01 0:00:00+0' +AND time <= '2000-01-05 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 1 | 3596 + 2 | 3596 + 3 | 3596 + 4 | 3596 + 5 | 3596 +(5 rows) + +SET enable_seqscan = default; +-- 1. drop column after first insert into chunk, before compressing +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-07 0:00:00+0'::timestamptz,'2000-01-09 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE compression_insert DROP COLUMN filler_1; +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-10 0:00:00+0'::timestamptz,'2000-01-11 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-07 0:00:00+0' +AND time <= '2000-01-11 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + HashAggregate + Group Key: _hyper_31_107_chunk.device_id + -> Append + -> Custom Scan (DecompressChunk) on _hyper_31_107_chunk + -> Index Scan using compress_hyper_32_108_chunk__compressed_hypertable_32_device_id on compress_hyper_32_108_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_109_chunk + -> Index Scan using compress_hyper_32_110_chunk__compressed_hypertable_32_device_id on compress_hyper_32_110_chunk + -> Index Only Scan using _hyper_31_109_chunk_compression_insert_device_id_time_idx on _hyper_31_109_chunk +(8 rows) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 7192 + 5 | 7192 + 4 | 7192 + 2 | 7192 + 1 | 7192 +(5 rows) + +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-07 0:00:00+0' +AND time <= '2000-01-11 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 7192 + 5 | 7192 + 4 | 7192 + 2 | 7192 + 1 | 7192 +(5 rows) + +SET enable_seqscan = default; +-- 2. drop column after compressing chunk +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-15 0:00:00+0'::timestamptz,'2000-01-17 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset +ALTER TABLE compression_insert DROP COLUMN filler_2; +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-18 0:00:00+0'::timestamptz,'2000-01-19 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-15 0:00:00+0' +AND time <= '2000-01-19 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + HashAggregate + Group Key: _hyper_31_107_chunk.device_id + -> Append + -> Custom Scan (DecompressChunk) on _hyper_31_107_chunk + -> Index Scan using compress_hyper_32_108_chunk__compressed_hypertable_32_device_id on compress_hyper_32_108_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_109_chunk + -> Index Scan using compress_hyper_32_110_chunk__compressed_hypertable_32_device_id on compress_hyper_32_110_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_111_chunk + -> Index Scan using compress_hyper_32_112_chunk__compressed_hypertable_32_device_id on compress_hyper_32_112_chunk + -> Index Only Scan using _hyper_31_111_chunk_compression_insert_device_id_time_idx on _hyper_31_111_chunk +(10 rows) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 10788 + 5 | 10788 + 4 | 10788 + 2 | 10788 + 1 | 10788 +(5 rows) + +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-15 0:00:00+0' +AND time <= '2000-01-19 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 10788 + 5 | 10788 + 4 | 10788 + 2 | 10788 + 1 | 10788 +(5 rows) + +SET enable_seqscan = default; +-- 3. add new column after first insert into chunk, before compressing +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-22 0:00:00+0'::timestamptz,'2000-01-24 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE compression_insert ADD COLUMN filler_4 int; +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-25 0:00:00+0'::timestamptz,'2000-01-26 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-22 0:00:00+0' +AND time <= '2000-01-26 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + HashAggregate + Group Key: _hyper_31_107_chunk.device_id + -> Append + -> Custom Scan (DecompressChunk) on _hyper_31_107_chunk + -> Index Scan using compress_hyper_32_108_chunk__compressed_hypertable_32_device_id on compress_hyper_32_108_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_109_chunk + -> Index Scan using compress_hyper_32_110_chunk__compressed_hypertable_32_device_id on compress_hyper_32_110_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_111_chunk + -> Index Scan using compress_hyper_32_112_chunk__compressed_hypertable_32_device_id on compress_hyper_32_112_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_113_chunk + -> Index Scan using compress_hyper_32_114_chunk__compressed_hypertable_32_device_id on compress_hyper_32_114_chunk + -> Index Only Scan using _hyper_31_113_chunk_compression_insert_device_id_time_idx on _hyper_31_113_chunk +(12 rows) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 14384 + 5 | 14384 + 4 | 14384 + 2 | 14384 + 1 | 14384 +(5 rows) + +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-22 0:00:00+0' +AND time <= '2000-01-26 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 14384 + 5 | 14384 + 4 | 14384 + 2 | 14384 + 1 | 14384 +(5 rows) + +SET enable_seqscan = default; +-- 4. add new column after compressing chunk +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-28 0:00:00+0'::timestamptz,'2000-01-30 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset +ALTER TABLE compression_insert ADD COLUMN filler_5 int; +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-31 0:00:00+0'::timestamptz,'2000-02-01 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-28 0:00:00+0' +AND time <= '2000-02-01 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + HashAggregate + Group Key: _hyper_31_107_chunk.device_id + -> Append + -> Custom Scan (DecompressChunk) on _hyper_31_107_chunk + -> Index Scan using compress_hyper_32_108_chunk__compressed_hypertable_32_device_id on compress_hyper_32_108_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_109_chunk + -> Index Scan using compress_hyper_32_110_chunk__compressed_hypertable_32_device_id on compress_hyper_32_110_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_111_chunk + -> Index Scan using compress_hyper_32_112_chunk__compressed_hypertable_32_device_id on compress_hyper_32_112_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_113_chunk + -> Index Scan using compress_hyper_32_114_chunk__compressed_hypertable_32_device_id on compress_hyper_32_114_chunk + -> Custom Scan (DecompressChunk) on _hyper_31_115_chunk + -> Index Scan using compress_hyper_32_116_chunk__compressed_hypertable_32_device_id on compress_hyper_32_116_chunk + -> Index Only Scan using _hyper_31_115_chunk_compression_insert_device_id_time_idx on _hyper_31_115_chunk +(14 rows) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 17980 + 5 | 17980 + 4 | 17980 + 2 | 17980 + 1 | 17980 +(5 rows) + +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-28 0:00:00+0' +AND time <= '2000-02-01 23:55:00+0'; + count | sum | sum | sum | sum +-------+-------+-------+-------+----- + 17980 | 71920 | 89900 | 62930 | +(1 row) + +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; + device_id | count +-----------+------- + 3 | 17980 + 5 | 17980 + 4 | 17980 + 2 | 17980 + 1 | 17980 +(5 rows) + +SET enable_seqscan = default; +DROP TABLE compression_insert; diff --git a/tsl/test/sql/compression_ddl.sql b/tsl/test/sql/compression_ddl.sql index ecd22caa879..1a4cd382bb4 100644 --- a/tsl/test/sql/compression_ddl.sql +++ b/tsl/test/sql/compression_ddl.sql @@ -610,3 +610,214 @@ ALTER MATERIALIZED VIEW test1_cont_view2 SET ( ); DROP TABLE metric CASCADE; + +-- inserting into compressed chunks with different physical layouts +CREATE TABLE compression_insert(filler_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 int, v2 float, v3 float); +CREATE INDEX ON compression_insert(time); +CREATE INDEX ON compression_insert(device_id,time); +SELECT create_hypertable('compression_insert','time',create_default_indexes:=false); +ALTER TABLE compression_insert SET (timescaledb.compress, timescaledb.compress_orderby='time DESC', timescaledb.compress_segmentby='device_id'); + +-- test without altering physical layout +-- this is a baseline test to compare results with +-- next series of tests which should yield identical results +-- while changing the physical layouts of chunks +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-03 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); + +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id and ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset + +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-04 0:00:00+0'::timestamptz,'2000-01-05 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-01 0:00:00+0' +AND time <= '2000-01-05 23:55:00+0'; + +-- force index scans to check index mapping +-- this verifies that we are actually using compressed chunk index scans +-- previously we could not use indexes on uncompressed chunks due to a bug: +-- https://github.com/timescale/timescaledb/issues/5432 +-- +-- this check basically makes sure that the indexes are built properly +-- and there are no issues in attribute mappings while building them +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-01 0:00:00+0' +AND time <= '2000-01-05 23:55:00+0'; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SET enable_seqscan = default; + +-- 1. drop column after first insert into chunk, before compressing +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-07 0:00:00+0'::timestamptz,'2000-01-09 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); + +ALTER TABLE compression_insert DROP COLUMN filler_1; +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset + +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-10 0:00:00+0'::timestamptz,'2000-01-11 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); + +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-07 0:00:00+0' +AND time <= '2000-01-11 23:55:00+0'; + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-07 0:00:00+0' +AND time <= '2000-01-11 23:55:00+0'; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SET enable_seqscan = default; + +-- 2. drop column after compressing chunk +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-15 0:00:00+0'::timestamptz,'2000-01-17 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); + +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset + +ALTER TABLE compression_insert DROP COLUMN filler_2; +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-18 0:00:00+0'::timestamptz,'2000-01-19 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-15 0:00:00+0' +AND time <= '2000-01-19 23:55:00+0'; + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-15 0:00:00+0' +AND time <= '2000-01-19 23:55:00+0'; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SET enable_seqscan = default; + +-- 3. add new column after first insert into chunk, before compressing +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-22 0:00:00+0'::timestamptz,'2000-01-24 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); + +ALTER TABLE compression_insert ADD COLUMN filler_4 int; +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset + +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-25 0:00:00+0'::timestamptz,'2000-01-26 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-22 0:00:00+0' +AND time <= '2000-01-26 23:55:00+0'; + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-22 0:00:00+0' +AND time <= '2000-01-26 23:55:00+0'; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SET enable_seqscan = default; + +-- 4. add new column after compressing chunk +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-28 0:00:00+0'::timestamptz,'2000-01-30 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) as "CHUNK_NAME" +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht +WHERE c.hypertable_id = ht.id +AND ht.table_name = 'compression_insert' +AND c.compressed_chunk_id IS NULL +ORDER BY c.table_name DESC \gset + +ALTER TABLE compression_insert ADD COLUMN filler_5 int; +INSERT INTO compression_insert(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-31 0:00:00+0'::timestamptz,'2000-02-01 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-28 0:00:00+0' +AND time <= '2000-02-01 23:55:00+0'; + +-- force index scans to check index mapping +SET enable_seqscan = off; +EXPLAIN (costs off) SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +CALL recompress_chunk(:'CHUNK_NAME'::regclass); +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) +FROM compression_insert +WHERE time >= '2000-01-28 0:00:00+0' +AND time <= '2000-02-01 23:55:00+0'; +SELECT device_id, count(*) +FROM compression_insert +GROUP BY device_id; +SET enable_seqscan = default; + +DROP TABLE compression_insert;