Add support for startup chunk exclusion with aggs

In ba9b81854c8c94005793bccff29433f6086e5274 we added support for
chunk-wise aggregates. The pushdown of the aggregate breaks the startup
exclusion logic of the ChunkAppend node. This PR adds the support for
startup chunk exclusion with chunk-wise aggs.

Fixes: #6282
This commit is contained in:
Jan Nidzwetzki 2023-11-07 11:00:53 +01:00 committed by Jan Nidzwetzki
parent 1b3f4a7035
commit e90280a07e
4 changed files with 47 additions and 1 deletions

1
.unreleased/fix_6289 Normal file
View File

@ -0,0 +1 @@
Fixes: #6289 Add support for startup chunk exclusion with aggs

View File

@ -401,10 +401,17 @@ ts_chunk_append_get_scan_plan(Plan *plan)
else
return NULL;
break;
case T_MergeAppend:
case T_Agg:
if (plan->lefttree != NULL && IsA(plan->lefttree, CustomScan))
{
Assert(plan->righttree == NULL);
Assert(castNode(CustomScan, plan->lefttree)->scan.scanrelid > 0);
return (Scan *) plan->lefttree;
}
return NULL;
break;
case T_MergeAppend:
return NULL;
default:
elog(ERROR, "invalid child of chunk append: %s", ts_get_node_name((Node *) plan));
}

View File

@ -153,6 +153,40 @@ SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >=
Filter: ((_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (_hyper_1_2_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone))
(35 rows)
-- Perform chunk append startup chunk exclusion - issue 6282
:PREFIX
SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-09 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'::text::timestamptz;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (actual rows=1 loops=1)
Output: count(*), sum(testtable.v0), sum(testtable.v1), sum(testtable.v2), sum(testtable.v3)
-> Custom Scan (ChunkAppend) on public.testtable (actual rows=3 loops=1)
Output: (PARTIAL count(*)), (PARTIAL sum(testtable.v0)), (PARTIAL sum(testtable.v1)), (PARTIAL sum(testtable.v2)), (PARTIAL sum(testtable.v3))
Startup Exclusion: true
Runtime Exclusion: false
Chunks excluded during startup: 1
-> Partial Aggregate (actual rows=1 loops=1)
Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3)
-> Index Scan using _hyper_1_1_chunk_testtable_time_idx on _timescaledb_internal._hyper_1_1_chunk (actual rows=0 loops=1)
Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3
Index Cond: ((_hyper_1_1_chunk."time" >= ('2000-01-09 00:00:00+0'::cstring)::timestamp with time zone) AND (_hyper_1_1_chunk."time" <= ('2000-02-01 00:00:00+0'::cstring)::timestamp with time zone))
-> Partial Aggregate (actual rows=1 loops=1)
Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3)
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_2_chunk (actual rows=10 loops=1)
Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3
Vectorized Filter: ((_hyper_1_2_chunk."time" >= ('2000-01-09 00:00:00+0'::cstring)::timestamp with time zone) AND (_hyper_1_2_chunk."time" <= ('2000-02-01 00:00:00+0'::cstring)::timestamp with time zone))
Rows Removed by Filter: 15
Bulk Decompression: true
-> Seq Scan on _timescaledb_internal.compress_hyper_2_4_chunk (actual rows=5 loops=1)
Output: compress_hyper_2_4_chunk.filter_1, compress_hyper_2_4_chunk.filler_2, compress_hyper_2_4_chunk.filler_3, compress_hyper_2_4_chunk."time", compress_hyper_2_4_chunk.device_id, compress_hyper_2_4_chunk.v0, compress_hyper_2_4_chunk.v1, compress_hyper_2_4_chunk.v2, compress_hyper_2_4_chunk.v3, compress_hyper_2_4_chunk._ts_meta_count, compress_hyper_2_4_chunk._ts_meta_sequence_num, compress_hyper_2_4_chunk._ts_meta_min_1, compress_hyper_2_4_chunk._ts_meta_max_1
Filter: ((compress_hyper_2_4_chunk._ts_meta_max_1 >= ('2000-01-09 00:00:00+0'::cstring)::timestamp with time zone) AND (compress_hyper_2_4_chunk._ts_meta_min_1 <= ('2000-02-01 00:00:00+0'::cstring)::timestamp with time zone))
-> Partial Aggregate (actual rows=1 loops=1)
Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3)
-> Index Scan using _hyper_1_2_chunk_testtable_time_idx on _timescaledb_internal._hyper_1_2_chunk (actual rows=10 loops=1)
Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3
Index Cond: ((_hyper_1_2_chunk."time" >= ('2000-01-09 00:00:00+0'::cstring)::timestamp with time zone) AND (_hyper_1_2_chunk."time" <= ('2000-02-01 00:00:00+0'::cstring)::timestamp with time zone))
(27 rows)
-- Force plain / sorted aggregation
SET enable_hashagg = OFF;
SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0';

View File

@ -42,6 +42,10 @@ SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >=
:PREFIX
SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0';
-- Perform chunk append startup chunk exclusion - issue 6282
:PREFIX
SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-09 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'::text::timestamptz;
-- Force plain / sorted aggregation
SET enable_hashagg = OFF;