diff --git a/src/guc.c b/src/guc.c index 744e2ba9f..1237a63c0 100644 --- a/src/guc.c +++ b/src/guc.c @@ -43,6 +43,7 @@ bool ts_guc_enable_chunk_append = true; bool ts_guc_enable_parallel_chunk_append = true; bool ts_guc_enable_runtime_exclusion = true; bool ts_guc_enable_constraint_exclusion = true; +bool ts_guc_enable_cagg_reorder_groupby = true; TSDLLEXPORT bool ts_guc_enable_transparent_decompression = true; int ts_guc_max_open_chunks_per_insert = 10; int ts_guc_max_cached_chunks_per_hypertable = 10; @@ -180,6 +181,17 @@ _guc_init(void) NULL, NULL); + DefineCustomBoolVariable("timescaledb.enable_cagg_reorder_groupby", + "Enable group by reordering", + "Enable group by clause reordering for continuous aggregates", + &ts_guc_enable_cagg_reorder_groupby, + true, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + DefineCustomIntVariable("timescaledb.max_open_chunks_per_insert", "Maximum open chunks per insert", "Maximum number of open chunk tables per insert", diff --git a/src/guc.h b/src/guc.h index 8150162e7..8a6088689 100644 --- a/src/guc.h +++ b/src/guc.h @@ -19,6 +19,7 @@ extern bool ts_guc_enable_chunk_append; extern bool ts_guc_enable_parallel_chunk_append; extern bool ts_guc_enable_runtime_exclusion; extern bool ts_guc_enable_constraint_exclusion; +extern bool ts_guc_enable_cagg_reorder_groupby; extern TSDLLEXPORT bool ts_guc_enable_transparent_decompression; extern bool ts_guc_restoring; extern int ts_guc_max_open_chunks_per_insert; diff --git a/src/planner.c b/src/planner.c index 6603c6b4b..5cb1d74e7 100644 --- a/src/planner.c +++ b/src/planner.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "compat.h" @@ -60,11 +61,19 @@ void _planner_init(void); void _planner_fini(void); +typedef struct TimescaledbWalkerState +{ + CmdType cmdtype; + Cache *hc; +} TimescaledbWalkerState; + static planner_hook_type prev_planner_hook; static set_rel_pathlist_hook_type prev_set_rel_pathlist_hook; static get_relation_info_hook_type prev_get_relation_info_hook; static create_upper_paths_hook_type prev_create_upper_paths_hook; static bool contain_param(Node *node); +static void cagg_reorder_groupby_clause(RangeTblEntry *subq_rte, int rtno, List *outer_sortcl, + List *outer_tlist); #define CTE_NAME_HYPERTABLES "hypertable_parent" @@ -89,11 +98,11 @@ is_rte_hypertable(RangeTblEntry *rte) * expansion ourselves. This prevents postgres from expanding the inheritance * tree itself. We will expand the chunks in timescaledb_get_relation_info_hook. */ static bool -turn_off_inheritance_walker(Node *node, Cache *hc) +timescaledb_query_walker(Node *node, TimescaledbWalkerState *cxt) { if (node == NULL) return false; - + Assert(cxt->cmdtype == CMD_INSERT || (cxt->cmdtype == CMD_SELECT)); if (IsA(node, Query)) { Query *query = (Query *) node; @@ -103,9 +112,18 @@ turn_off_inheritance_walker(Node *node, Cache *hc) foreach (lc, query->rtable) { RangeTblEntry *rte = lfirst(lc); - - if (rte->inh) + if (rte->rtekind == RTE_SUBQUERY && cxt->cmdtype == CMD_SELECT && + ts_guc_enable_cagg_reorder_groupby) { + /* applicable to selects on continuous aggregates */ + List *outer_tlist = query->targetList; + List *outer_sortcl = query->sortClause; + cagg_reorder_groupby_clause(rte, rti, outer_sortcl, outer_tlist); + } + else if (rte->inh && ts_guc_enable_constraint_exclusion) + { + /* turn off inheritance on hypertables for inserts and selects*/ + Cache *hc = cxt->hc; Hypertable *ht = ts_hypertable_cache_get_entry(hc, rte->relid); if (NULL != ht && ts_plan_expand_hypertable_valid_hypertable(ht, query, rti, rte)) @@ -117,10 +135,10 @@ turn_off_inheritance_walker(Node *node, Cache *hc) rti++; } - return query_tree_walker(query, turn_off_inheritance_walker, hc, 0); + return query_tree_walker(query, timescaledb_query_walker, cxt, 0); } - return expression_tree_walker(node, turn_off_inheritance_walker, hc); + return expression_tree_walker(node, timescaledb_query_walker, cxt); } static PlannedStmt * @@ -128,22 +146,48 @@ timescaledb_planner(Query *parse, int cursor_opts, ParamListInfo bound_params) { PlannedStmt *stmt; ListCell *lc; - - if (ts_extension_is_loaded() && !ts_guc_disable_optimizations && - ts_guc_enable_constraint_exclusion && - (parse->commandType == CMD_INSERT || parse->commandType == CMD_SELECT)) + if (ts_extension_is_loaded() && !ts_guc_disable_optimizations) { - Cache *hc = ts_hypertable_cache_pin(); + TimescaledbWalkerState cxt; + Query *node_arg = NULL; + if (ts_guc_enable_cagg_reorder_groupby && (parse->commandType == CMD_UTILITY)) + { + Query *modq = NULL; + if ((nodeTag(parse->utilityStmt) == T_ExplainStmt)) + { + modq = (Query *) ((ExplainStmt *) parse->utilityStmt)->query; + } - /* - * turn of inheritance on hypertables we will expand ourselves in - * timescaledb_get_relation_info_hook - */ - turn_off_inheritance_walker((Node *) parse, hc); + if (modq && modq->commandType == CMD_SELECT) + { + cxt.cmdtype = CMD_SELECT; + node_arg = modq; + } + } + else if (parse->commandType == CMD_INSERT && ts_guc_enable_constraint_exclusion) + { + cxt.cmdtype = CMD_INSERT; + node_arg = parse; + } + else if (parse->commandType == CMD_SELECT && + (ts_guc_enable_constraint_exclusion || ts_guc_enable_cagg_reorder_groupby)) + { + cxt.cmdtype = CMD_SELECT; + node_arg = parse; + } + if (node_arg) + { + Cache *hc = ts_hypertable_cache_pin(); + cxt.hc = hc; + /* + * turn of inheritance on hypertables we will expand ourselves in + * timescaledb_get_relation_info_hook + */ + timescaledb_query_walker((Node *) node_arg, &cxt); - ts_cache_release(hc); + ts_cache_release(hc); + } } - if (prev_planner_hook != NULL) /* Call any earlier hooks */ stmt = (prev_planner_hook)(parse, cursor_opts, bound_params); @@ -487,7 +531,7 @@ timescaledb_get_relation_info_hook(PlannerInfo *root, Oid relation_objectid, boo /* * We expand the hypertable chunks into an append relation. Previously, in - * `turn_off_inheritance_walker` we suppressed this expansion. This hook + * `timescaledb_query_walker` we suppressed this expansion. This hook * is really the first one that's called after the initial planner setup * and so it's convenient to do the expansion here. Note that this is * after the usual expansion happens in `expand_inherited_tables` (called @@ -737,6 +781,121 @@ contain_param(Node *node) return contain_param_exec_walker(node, NULL); } +static List * +fill_missing_groupclause(List *new_groupclause, List *orig_groupclause) +{ + if (new_groupclause != NIL) + { + ListCell *gl; + foreach (gl, orig_groupclause) + { + SortGroupClause *gc = lfirst_node(SortGroupClause, gl); + + if (list_member_ptr(new_groupclause, gc)) + continue; /* already in list */ + new_groupclause = lappend(new_groupclause, gc); + } + } + return new_groupclause; +} + +static bool +check_cagg_view_rte(RangeTblEntry *rte) +{ + ContinuousAgg *cagg = NULL; + ListCell *rtlc; + bool found = false; + Query *viewq = rte->subquery; + Assert(rte->rtekind == RTE_SUBQUERY); + + if (list_length(viewq->rtable) != 3) /* a view has 3 entries */ + { + return false; + } + + // should cache this information for cont. aggregates + foreach (rtlc, viewq->rtable) + { + RangeTblEntry *rte = (RangeTblEntry *) lfirst(rtlc); + char *schema; + char *table; + + if (!OidIsValid(rte->relid)) + break; + + schema = get_namespace_name(get_rel_namespace(rte->relid)); + table = get_rel_name(rte->relid); + if ((cagg = ts_continuous_agg_find_by_view_name(schema, table)) != NULL) + found = true; + } + return found; +} + +/* Note that it modifies the passed in Query +* select * from (select a, b, max(c), min(d) from ... + group by a, b) + order by b; +* is transformed as +* SELECT * from (select a, b, max(c), min(d) from .. +* group by B desc, A <------ note the change in order here +* ) +* order by b desc; +* we transform only if order by is a subset of group-by +* transformation is applicable only to continuous aggregates +* Parameters: +* subq_rte - rte for subquery (inner query that will be modified) +* outer_sortcl -- outer query's sort clause +* outer_tlist - outer query's target list +*/ +static void +cagg_reorder_groupby_clause(RangeTblEntry *subq_rte, int rtno, List *outer_sortcl, + List *outer_tlist) +{ + bool not_found = true; + Query *subq; + ListCell *lc; + Assert(subq_rte->rtekind == RTE_SUBQUERY); + subq = subq_rte->subquery; + if (outer_sortcl && subq->groupClause && subq->sortClause == NIL && + check_cagg_view_rte(subq_rte)) + { + List *new_groupclause = NIL; + /* we are going to modify this. so make a copy and use it + if we replace */ + List *subq_groupclause_copy = copyObject(subq->groupClause); + foreach (lc, outer_sortcl) + { + SortGroupClause *outer_sc = (SortGroupClause *) lfirst(lc); + TargetEntry *outer_tle = get_sortgroupclause_tle(outer_sc, outer_tlist); + not_found = true; + if (IsA(outer_tle->expr, Var) && (((Var *) outer_tle->expr)->varno == rtno)) + { + int outer_attno = ((Var *) outer_tle->expr)->varattno; + TargetEntry *subq_tle = list_nth(subq->targetList, outer_attno - 1); + if (subq_tle->ressortgroupref > 0) + { + /* get group clause corresponding to this */ + SortGroupClause *subq_gclause = + get_sortgroupref_clause(subq_tle->ressortgroupref, subq_groupclause_copy); + subq_gclause->sortop = outer_sc->sortop; + subq_gclause->nulls_first = outer_sc->nulls_first; + Assert(subq_gclause->eqop == outer_sc->eqop); + new_groupclause = lappend(new_groupclause, subq_gclause); + not_found = false; + } + } + if (not_found) + break; + } + /* all order by found in group by clause */ + if (new_groupclause != NIL && not_found == false) + { + /* use new groupby clause for this subquery/view */ + subq->groupClause = fill_missing_groupclause(new_groupclause, subq_groupclause_copy); + } + } +} + void _planner_init(void) { diff --git a/tsl/test/expected/continuous_aggs_query-10.out b/tsl/test/expected/continuous_aggs_query-10.out new file mode 100644 index 000000000..f72a7506b --- /dev/null +++ b/tsl/test/expected/continuous_aggs_query-10.out @@ -0,0 +1,408 @@ +-- 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. +\c :TEST_DBNAME :ROLE_SUPERUSER +-- stop the continous aggregate background workers from interfering +SELECT _timescaledb_internal.stop_background_workers(); + stop_background_workers +------------------------- + t +(1 row) + +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +\set TEST_BASE_NAME continuous_aggs_query +SELECT + format('%s/results/%s_results_view.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW", + format('%s/results/%s_results_view_hashagg.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW_HASHAGG", + format('%s/results/%s_results_table.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_TABLE" +\gset +SELECT format('\! diff %s %s', :'TEST_RESULTS_VIEW', :'TEST_RESULTS_TABLE') as "DIFF_CMD", + format('\! diff %s %s', :'TEST_RESULTS_VIEW_HASHAGG', :'TEST_RESULTS_TABLE') as "DIFF_CMD2" +\gset +\set ON_ERROR_STOP 0 +CREATE TABLE conditions ( + timec TIMESTAMPTZ NOT NULL, + location TEXT NOT NULL, + temperature DOUBLE PRECISION NULL, + humidity DOUBLE PRECISION NULL + ); +select table_name from create_hypertable( 'conditions', 'timec'); + table_name +------------ + conditions +(1 row) + +insert into conditions values ( '2018-01-01 09:00:00-08', 'SFO', 55, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'por', 100, 100); +insert into conditions values ( '2018-01-02 09:00:00-08', 'SFO', 65, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'NYC', 65, 45); +insert into conditions values ( '2018-11-01 09:00:00-08', 'NYC', 45, 30); +insert into conditions values ( '2018-11-01 10:00:00-08', 'NYC', 55, 35); +insert into conditions values ( '2018-11-01 11:00:00-08', 'NYC', 65, 40); +insert into conditions values ( '2018-11-01 12:00:00-08', 'NYC', 75, 45); +insert into conditions values ( '2018-11-01 13:00:00-08', 'NYC', 85, 50); +insert into conditions values ( '2018-11-02 09:00:00-08', 'NYC', 10, 10); +insert into conditions values ( '2018-11-02 10:00:00-08', 'NYC', 20, 15); +insert into conditions values ( '2018-11-02 11:00:00-08', 'NYC', null, null); +insert into conditions values ( '2018-11-03 09:00:00-08', 'NYC', null, null); +create table location_tab( locid integer, locname text ); +insert into location_tab values( 1, 'SFO'); +insert into location_tab values( 2, 'NYC'); +insert into location_tab values( 3, 'por'); +create or replace view mat_m1( location, timec, minl, sumt , sumh) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by time_bucket('1day', timec), location; +NOTICE: adding index _materialized_hypertable_2_location_timec_idx ON _timescaledb_internal._materialized_hypertable_2 USING BTREE(location, timec) +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m1; +INFO: new materialization range for public.conditions (time column timec) (1546041600000000) +INFO: materializing continuous aggregate public.mat_m1: nothing to invalidate, new range up to 1546041600000000 +--test first/last +create or replace view mat_m2(location, timec, firsth, lasth, maxtemp, mintemp) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), first(humidity, timec), last(humidity, timec), max(temperature), min(temperature) +from conditions +group by time_bucket('1day', timec), location; +NOTICE: adding index _materialized_hypertable_3_location_timec_idx ON _timescaledb_internal._materialized_hypertable_3 USING BTREE(location, timec) +--time that refresh assumes as now() for repeatability +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m2; +INFO: new materialization range for public.conditions (time column timec) (1546041600000000) +INFO: materializing continuous aggregate public.mat_m2: nothing to invalidate, new range up to 1546041600000000 +--normal view -- +create or replace view regview( location, timec, minl, sumt , sumh) +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by location, time_bucket('1day', timec); +set enable_hashagg = false; +-- NO pushdown cases --- +--when we have addl. attrs in order by that are not in the +-- group by, we will still need a sort +explain verbose +select * from mat_m1 order by sumh, sumt, minl, timec ; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (cost=104.70..105.20 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)) + Sort Key: (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), _hyper_2_3_chunk.timec + -> GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(14 rows) + +explain verbose +select * from regview order by timec desc; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort (cost=210.84..211.34 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) DESC + -> GroupAggregate (cost=169.59..201.19 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), min(_hyper_1_1_chunk.location), sum(_hyper_1_1_chunk.temperature), sum(_hyper_1_1_chunk.humidity) + Group Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Sort (cost=169.59..174.44 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + Sort Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Result (cost=0.00..63.65 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Append (cost=0.00..39.40 rows=1940 width=56) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_1_chunk.location, _hyper_1_1_chunk.timec, _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_2_chunk.location, _hyper_1_2_chunk.timec, _hyper_1_2_chunk.temperature, _hyper_1_2_chunk.humidity +(16 rows) + +-- PUSHDOWN cases -- +-- all group by elts in order by , reorder group by elts to match +-- group by order +-- This should prevent an additional sort after GroupAggregate +explain verbose +select * from mat_m1 order by timec desc, location; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec DESC, _hyper_2_3_chunk.location + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(11 rows) + +explain verbose +select * from mat_m1 order by location, timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=0.30..61.41 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Merge Append (cost=0.30..45.91 rows=960 width=136) + Sort Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec DESC + -> Index Scan using _hyper_2_3_chunk__materialized_hypertable_2_location_timec_idx on _timescaledb_internal._hyper_2_3_chunk (cost=0.15..19.35 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_location_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..19.35 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(9 rows) + +explain verbose +select * from mat_m1 order by location, timec asc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(11 rows) + +explain verbose +select * from mat_m1 where timec > '2018-10-01' order by timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(10 rows) + +-- outer sort is used by mat_m1 for grouping. But doesn't avoid a sort after the join --- +explain verbose +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort (cost=116.97..119.51 rows=1016 width=92) + Output: l.locid, _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + Sort Key: _hyper_2_4_chunk.timec DESC + -> Hash Join (cost=28.61..66.23 rows=1016 width=92) + Output: l.locid, _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + Hash Cond: (l.locname = _hyper_2_4_chunk.location) + -> Seq Scan on public.location_tab l (cost=0.00..22.70 rows=1270 width=36) + Output: l.locid, l.locname + -> Hash (cost=26.61..26.61 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + -> GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(20 rows) + +explain verbose +select * from mat_m2 where timec > '2018-10-01' order by timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(10 rows) + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc ) as q limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (cost=18.17..18.22 rows=1 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision)) + -> GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(12 rows) + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc , location asc nulls first) as q limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (cost=18.17..18.22 rows=1 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision)) + -> GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location NULLS FIRST + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(12 rows) + +--plans with CTE +explain verbose +with m1 as ( +Select * from mat_m2 where timec > '2018-10-01' order by timec desc ) +select * from m1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on m1 (cost=24.48..27.14 rows=133 width=72) + Output: m1.location, m1.timec, m1.firsth, m1.lasth, m1.maxtemp, m1.mintemp + CTE m1 + -> GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(13 rows) + +-- should reorder mat_m1 group by only based on mat_m1 order-by +explain verbose +select * from mat_m1, mat_m2 where mat_m1.timec > '2018-10-01' and mat_m1.timec = mat_m2.timec order by mat_m1.timec desc; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (cost=114.02..123.82 rows=160 width=160) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)), _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision)) + Merge Cond: (_hyper_2_4_chunk.timec = _hyper_3_5_chunk.timec) + -> GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) + -> Sort (cost=94.22..94.72 rows=200 width=72) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision)) + Sort Key: _hyper_3_5_chunk.timec DESC + -> GroupAggregate (cost=66.58..84.58 rows=200 width=72) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_5_chunk.timec, _hyper_3_5_chunk.location + -> Sort (cost=66.58..68.58 rows=800 width=168) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _hyper_3_5_chunk.agg_3_3, _hyper_3_5_chunk.agg_4_4, _hyper_3_5_chunk.agg_5_5, _hyper_3_5_chunk.agg_6_6 + Sort Key: _hyper_3_5_chunk.timec, _hyper_3_5_chunk.location + -> Append (cost=0.00..28.00 rows=800 width=168) + -> Seq Scan on _timescaledb_internal._hyper_3_5_chunk (cost=0.00..14.00 rows=400 width=168) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _hyper_3_5_chunk.agg_3_3, _hyper_3_5_chunk.agg_4_4, _hyper_3_5_chunk.agg_5_5, _hyper_3_5_chunk.agg_6_6 + -> Seq Scan on _timescaledb_internal._hyper_3_6_chunk (cost=0.00..14.00 rows=400 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 +(27 rows) + +--should reorder only for mat_m1. +explain verbose +select * from mat_m1, regview where mat_m1.timec > '2018-10-01' and mat_m1.timec = regview.timec order by mat_m1.timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Merge Join (cost=230.64..240.44 rows=160 width=176) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)), _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Merge Cond: (_hyper_2_4_chunk.timec = (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec))) + -> GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) + -> Sort (cost=210.84..211.34 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) DESC + -> GroupAggregate (cost=169.59..201.19 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), min(_hyper_1_1_chunk.location), sum(_hyper_1_1_chunk.temperature), sum(_hyper_1_1_chunk.humidity) + Group Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Sort (cost=169.59..174.44 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + Sort Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Result (cost=0.00..63.65 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Append (cost=0.00..39.40 rows=1940 width=56) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_1_chunk.location, _hyper_1_1_chunk.timec, _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_2_chunk.location, _hyper_1_2_chunk.timec, _hyper_1_2_chunk.temperature, _hyper_1_2_chunk.humidity +(29 rows) + +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + locid | location | timec | minl | sumt | sumh +-------+----------+------------------------------+------+------+------ + 2 | NYC | Fri Nov 02 17:00:00 2018 PDT | NYC | | + 2 | NYC | Thu Nov 01 17:00:00 2018 PDT | NYC | 30 | 25 + 2 | NYC | Wed Oct 31 17:00:00 2018 PDT | NYC | 325 | 200 +(3 rows) + +\set ECHO none +---- Run the same queries with hash agg enabled now +set enable_hashagg = true; +\set ECHO none +--- Run the queries directly on the table now +set enable_hashagg = true; +\set ECHO none +-- diff results view select and table select +:DIFF_CMD +:DIFF_CMD2 +--check if the guc works , reordering will not work +set timescaledb.enable_cagg_reorder_groupby = false; +set enable_hashagg = false; +explain verbose +select * from mat_m1 order by timec desc, location; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (cost=104.70..105.20 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)) + Sort Key: _hyper_2_3_chunk.timec DESC, _hyper_2_3_chunk.location + -> GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(14 rows) + diff --git a/tsl/test/expected/continuous_aggs_query-11.out b/tsl/test/expected/continuous_aggs_query-11.out new file mode 100644 index 000000000..c103e751c --- /dev/null +++ b/tsl/test/expected/continuous_aggs_query-11.out @@ -0,0 +1,408 @@ +-- 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. +\c :TEST_DBNAME :ROLE_SUPERUSER +-- stop the continous aggregate background workers from interfering +SELECT _timescaledb_internal.stop_background_workers(); + stop_background_workers +------------------------- + t +(1 row) + +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +\set TEST_BASE_NAME continuous_aggs_query +SELECT + format('%s/results/%s_results_view.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW", + format('%s/results/%s_results_view_hashagg.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW_HASHAGG", + format('%s/results/%s_results_table.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_TABLE" +\gset +SELECT format('\! diff %s %s', :'TEST_RESULTS_VIEW', :'TEST_RESULTS_TABLE') as "DIFF_CMD", + format('\! diff %s %s', :'TEST_RESULTS_VIEW_HASHAGG', :'TEST_RESULTS_TABLE') as "DIFF_CMD2" +\gset +\set ON_ERROR_STOP 0 +CREATE TABLE conditions ( + timec TIMESTAMPTZ NOT NULL, + location TEXT NOT NULL, + temperature DOUBLE PRECISION NULL, + humidity DOUBLE PRECISION NULL + ); +select table_name from create_hypertable( 'conditions', 'timec'); + table_name +------------ + conditions +(1 row) + +insert into conditions values ( '2018-01-01 09:00:00-08', 'SFO', 55, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'por', 100, 100); +insert into conditions values ( '2018-01-02 09:00:00-08', 'SFO', 65, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'NYC', 65, 45); +insert into conditions values ( '2018-11-01 09:00:00-08', 'NYC', 45, 30); +insert into conditions values ( '2018-11-01 10:00:00-08', 'NYC', 55, 35); +insert into conditions values ( '2018-11-01 11:00:00-08', 'NYC', 65, 40); +insert into conditions values ( '2018-11-01 12:00:00-08', 'NYC', 75, 45); +insert into conditions values ( '2018-11-01 13:00:00-08', 'NYC', 85, 50); +insert into conditions values ( '2018-11-02 09:00:00-08', 'NYC', 10, 10); +insert into conditions values ( '2018-11-02 10:00:00-08', 'NYC', 20, 15); +insert into conditions values ( '2018-11-02 11:00:00-08', 'NYC', null, null); +insert into conditions values ( '2018-11-03 09:00:00-08', 'NYC', null, null); +create table location_tab( locid integer, locname text ); +insert into location_tab values( 1, 'SFO'); +insert into location_tab values( 2, 'NYC'); +insert into location_tab values( 3, 'por'); +create or replace view mat_m1( location, timec, minl, sumt , sumh) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by time_bucket('1day', timec), location; +NOTICE: adding index _materialized_hypertable_2_location_timec_idx ON _timescaledb_internal._materialized_hypertable_2 USING BTREE(location, timec) +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m1; +INFO: new materialization range for public.conditions (time column timec) (1546041600000000) +INFO: materializing continuous aggregate public.mat_m1: nothing to invalidate, new range up to 1546041600000000 +--test first/last +create or replace view mat_m2(location, timec, firsth, lasth, maxtemp, mintemp) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), first(humidity, timec), last(humidity, timec), max(temperature), min(temperature) +from conditions +group by time_bucket('1day', timec), location; +NOTICE: adding index _materialized_hypertable_3_location_timec_idx ON _timescaledb_internal._materialized_hypertable_3 USING BTREE(location, timec) +--time that refresh assumes as now() for repeatability +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m2; +INFO: new materialization range for public.conditions (time column timec) (1546041600000000) +INFO: materializing continuous aggregate public.mat_m2: nothing to invalidate, new range up to 1546041600000000 +--normal view -- +create or replace view regview( location, timec, minl, sumt , sumh) +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by location, time_bucket('1day', timec); +set enable_hashagg = false; +-- NO pushdown cases --- +--when we have addl. attrs in order by that are not in the +-- group by, we will still need a sort +explain verbose +select * from mat_m1 order by sumh, sumt, minl, timec ; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (cost=109.50..110.00 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)) + Sort Key: (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), _hyper_2_3_chunk.timec + -> GroupAggregate (cost=81.95..99.85 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=81.95..84.35 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Append (cost=0.00..34.40 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(14 rows) + +explain verbose +select * from regview order by timec desc; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort (cost=220.54..221.04 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) DESC + -> GroupAggregate (cost=179.29..210.89 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), min(_hyper_1_1_chunk.location), sum(_hyper_1_1_chunk.temperature), sum(_hyper_1_1_chunk.humidity) + Group Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Sort (cost=179.29..184.14 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + Sort Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Result (cost=0.00..73.35 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Append (cost=0.00..49.10 rows=1940 width=56) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_1_chunk.location, _hyper_1_1_chunk.timec, _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_2_chunk.location, _hyper_1_2_chunk.timec, _hyper_1_2_chunk.temperature, _hyper_1_2_chunk.humidity +(16 rows) + +-- PUSHDOWN cases -- +-- all group by elts in order by , reorder group by elts to match +-- group by order +-- This should prevent an additional sort after GroupAggregate +explain verbose +select * from mat_m1 order by timec desc, location; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=81.95..99.85 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=81.95..84.35 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec DESC, _hyper_2_3_chunk.location + -> Append (cost=0.00..34.40 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(11 rows) + +explain verbose +select * from mat_m1 order by location, timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=0.30..63.80 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Merge Append (cost=0.30..48.30 rows=960 width=136) + Sort Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec DESC + -> Index Scan using _hyper_2_3_chunk__materialized_hypertable_2_location_timec_idx on _timescaledb_internal._hyper_2_3_chunk (cost=0.15..19.35 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_location_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..19.35 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(9 rows) + +explain verbose +select * from mat_m1 order by location, timec asc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=81.95..99.85 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Sort (cost=81.95..84.35 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Append (cost=0.00..34.40 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(11 rows) + +explain verbose +select * from mat_m1 where timec > '2018-10-01' order by timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=20.61..25.81 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=20.61..21.01 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..14.75 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(10 rows) + +-- outer sort is used by mat_m1 for grouping. But doesn't avoid a sort after the join --- +explain verbose +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort (cost=117.77..120.31 rows=1016 width=92) + Output: l.locid, _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + Sort Key: _hyper_2_4_chunk.timec DESC + -> Hash Join (cost=29.41..67.03 rows=1016 width=92) + Output: l.locid, _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + Hash Cond: (l.locname = _hyper_2_4_chunk.location) + -> Seq Scan on public.location_tab l (cost=0.00..22.70 rows=1270 width=36) + Output: l.locid, l.locname + -> Hash (cost=27.41..27.41 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + -> GroupAggregate (cost=20.61..25.81 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=20.61..21.01 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..14.75 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(20 rows) + +explain verbose +select * from mat_m2 where timec > '2018-10-01' order by timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=18.83..23.82 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.83..19.16 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..14.14 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(10 rows) + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc ) as q limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (cost=18.83..18.89 rows=1 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision)) + -> GroupAggregate (cost=18.83..23.82 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.83..19.16 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..14.14 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(12 rows) + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc , location asc nulls first) as q limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (cost=18.83..18.89 rows=1 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision)) + -> GroupAggregate (cost=18.83..23.82 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.83..19.16 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location NULLS FIRST + -> Append (cost=0.15..14.14 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(12 rows) + +--plans with CTE +explain verbose +with m1 as ( +Select * from mat_m2 where timec > '2018-10-01' order by timec desc ) +select * from m1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on m1 (cost=25.15..27.81 rows=133 width=72) + Output: m1.location, m1.timec, m1.firsth, m1.lasth, m1.maxtemp, m1.mintemp + CTE m1 + -> GroupAggregate (cost=18.83..23.82 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.83..19.16 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..14.14 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(13 rows) + +-- should reorder mat_m1 group by only based on mat_m1 order-by +explain verbose +select * from mat_m1, mat_m2 where mat_m1.timec > '2018-10-01' and mat_m1.timec = mat_m2.timec order by mat_m1.timec desc; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (cost=118.82..128.62 rows=160 width=160) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)), _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision)) + Merge Cond: (_hyper_2_4_chunk.timec = _hyper_3_5_chunk.timec) + -> GroupAggregate (cost=20.61..25.81 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=20.61..21.01 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..14.75 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) + -> Sort (cost=98.22..98.72 rows=200 width=72) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision)) + Sort Key: _hyper_3_5_chunk.timec DESC + -> GroupAggregate (cost=70.58..88.58 rows=200 width=72) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_5_chunk.timec, _hyper_3_5_chunk.location + -> Sort (cost=70.58..72.58 rows=800 width=168) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _hyper_3_5_chunk.agg_3_3, _hyper_3_5_chunk.agg_4_4, _hyper_3_5_chunk.agg_5_5, _hyper_3_5_chunk.agg_6_6 + Sort Key: _hyper_3_5_chunk.timec, _hyper_3_5_chunk.location + -> Append (cost=0.00..32.00 rows=800 width=168) + -> Seq Scan on _timescaledb_internal._hyper_3_5_chunk (cost=0.00..14.00 rows=400 width=168) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _hyper_3_5_chunk.agg_3_3, _hyper_3_5_chunk.agg_4_4, _hyper_3_5_chunk.agg_5_5, _hyper_3_5_chunk.agg_6_6 + -> Seq Scan on _timescaledb_internal._hyper_3_6_chunk (cost=0.00..14.00 rows=400 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 +(27 rows) + +--should reorder only for mat_m1. +explain verbose +select * from mat_m1, regview where mat_m1.timec > '2018-10-01' and mat_m1.timec = regview.timec order by mat_m1.timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Merge Join (cost=241.14..250.94 rows=160 width=176) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)), _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Merge Cond: (_hyper_2_4_chunk.timec = (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec))) + -> GroupAggregate (cost=20.61..25.81 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=20.61..21.01 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..14.75 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) + -> Sort (cost=220.54..221.04 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) DESC + -> GroupAggregate (cost=179.29..210.89 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), min(_hyper_1_1_chunk.location), sum(_hyper_1_1_chunk.temperature), sum(_hyper_1_1_chunk.humidity) + Group Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Sort (cost=179.29..184.14 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + Sort Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Result (cost=0.00..73.35 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Append (cost=0.00..49.10 rows=1940 width=56) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_1_chunk.location, _hyper_1_1_chunk.timec, _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_2_chunk.location, _hyper_1_2_chunk.timec, _hyper_1_2_chunk.temperature, _hyper_1_2_chunk.humidity +(29 rows) + +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + locid | location | timec | minl | sumt | sumh +-------+----------+------------------------------+------+------+------ + 2 | NYC | Fri Nov 02 17:00:00 2018 PDT | NYC | | + 2 | NYC | Thu Nov 01 17:00:00 2018 PDT | NYC | 30 | 25 + 2 | NYC | Wed Oct 31 17:00:00 2018 PDT | NYC | 325 | 200 +(3 rows) + +\set ECHO none +---- Run the same queries with hash agg enabled now +set enable_hashagg = true; +\set ECHO none +--- Run the queries directly on the table now +set enable_hashagg = true; +\set ECHO none +-- diff results view select and table select +:DIFF_CMD +:DIFF_CMD2 +--check if the guc works , reordering will not work +set timescaledb.enable_cagg_reorder_groupby = false; +set enable_hashagg = false; +explain verbose +select * from mat_m1 order by timec desc, location; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (cost=109.50..110.00 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)) + Sort Key: _hyper_2_3_chunk.timec DESC, _hyper_2_3_chunk.location + -> GroupAggregate (cost=81.95..99.85 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=81.95..84.35 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Append (cost=0.00..34.40 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(14 rows) + diff --git a/tsl/test/expected/continuous_aggs_query-9.6.out b/tsl/test/expected/continuous_aggs_query-9.6.out new file mode 100644 index 000000000..d096ecdb5 --- /dev/null +++ b/tsl/test/expected/continuous_aggs_query-9.6.out @@ -0,0 +1,408 @@ +-- 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. +\c :TEST_DBNAME :ROLE_SUPERUSER +-- stop the continous aggregate background workers from interfering +SELECT _timescaledb_internal.stop_background_workers(); + stop_background_workers +------------------------- + t +(1 row) + +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +\set TEST_BASE_NAME continuous_aggs_query +SELECT + format('%s/results/%s_results_view.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW", + format('%s/results/%s_results_view_hashagg.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW_HASHAGG", + format('%s/results/%s_results_table.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_TABLE" +\gset +SELECT format('\! diff %s %s', :'TEST_RESULTS_VIEW', :'TEST_RESULTS_TABLE') as "DIFF_CMD", + format('\! diff %s %s', :'TEST_RESULTS_VIEW_HASHAGG', :'TEST_RESULTS_TABLE') as "DIFF_CMD2" +\gset +\set ON_ERROR_STOP 0 +CREATE TABLE conditions ( + timec TIMESTAMPTZ NOT NULL, + location TEXT NOT NULL, + temperature DOUBLE PRECISION NULL, + humidity DOUBLE PRECISION NULL + ); +select table_name from create_hypertable( 'conditions', 'timec'); + table_name +------------ + conditions +(1 row) + +insert into conditions values ( '2018-01-01 09:00:00-08', 'SFO', 55, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'por', 100, 100); +insert into conditions values ( '2018-01-02 09:00:00-08', 'SFO', 65, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'NYC', 65, 45); +insert into conditions values ( '2018-11-01 09:00:00-08', 'NYC', 45, 30); +insert into conditions values ( '2018-11-01 10:00:00-08', 'NYC', 55, 35); +insert into conditions values ( '2018-11-01 11:00:00-08', 'NYC', 65, 40); +insert into conditions values ( '2018-11-01 12:00:00-08', 'NYC', 75, 45); +insert into conditions values ( '2018-11-01 13:00:00-08', 'NYC', 85, 50); +insert into conditions values ( '2018-11-02 09:00:00-08', 'NYC', 10, 10); +insert into conditions values ( '2018-11-02 10:00:00-08', 'NYC', 20, 15); +insert into conditions values ( '2018-11-02 11:00:00-08', 'NYC', null, null); +insert into conditions values ( '2018-11-03 09:00:00-08', 'NYC', null, null); +create table location_tab( locid integer, locname text ); +insert into location_tab values( 1, 'SFO'); +insert into location_tab values( 2, 'NYC'); +insert into location_tab values( 3, 'por'); +create or replace view mat_m1( location, timec, minl, sumt , sumh) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by time_bucket('1day', timec), location; +NOTICE: adding index _materialized_hypertable_2_location_timec_idx ON _timescaledb_internal._materialized_hypertable_2 USING BTREE(location, timec) +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m1; +INFO: new materialization range for public.conditions (time column timec) (1546041600000000) +INFO: materializing continuous aggregate public.mat_m1: nothing to invalidate, new range up to 1546041600000000 +--test first/last +create or replace view mat_m2(location, timec, firsth, lasth, maxtemp, mintemp) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), first(humidity, timec), last(humidity, timec), max(temperature), min(temperature) +from conditions +group by time_bucket('1day', timec), location; +NOTICE: adding index _materialized_hypertable_3_location_timec_idx ON _timescaledb_internal._materialized_hypertable_3 USING BTREE(location, timec) +--time that refresh assumes as now() for repeatability +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m2; +INFO: new materialization range for public.conditions (time column timec) (1546041600000000) +INFO: materializing continuous aggregate public.mat_m2: nothing to invalidate, new range up to 1546041600000000 +--normal view -- +create or replace view regview( location, timec, minl, sumt , sumh) +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by location, time_bucket('1day', timec); +set enable_hashagg = false; +-- NO pushdown cases --- +--when we have addl. attrs in order by that are not in the +-- group by, we will still need a sort +explain verbose +select * from mat_m1 order by sumh, sumt, minl, timec ; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (cost=104.70..105.20 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)) + Sort Key: (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), _hyper_2_3_chunk.timec + -> GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(14 rows) + +explain verbose +select * from regview order by timec desc; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort (cost=210.84..211.34 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) DESC + -> GroupAggregate (cost=169.59..201.19 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), min(_hyper_1_1_chunk.location), sum(_hyper_1_1_chunk.temperature), sum(_hyper_1_1_chunk.humidity) + Group Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Sort (cost=169.59..174.44 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + Sort Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Result (cost=0.00..63.65 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Append (cost=0.00..39.40 rows=1940 width=56) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_1_chunk.location, _hyper_1_1_chunk.timec, _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_2_chunk.location, _hyper_1_2_chunk.timec, _hyper_1_2_chunk.temperature, _hyper_1_2_chunk.humidity +(16 rows) + +-- PUSHDOWN cases -- +-- all group by elts in order by , reorder group by elts to match +-- group by order +-- This should prevent an additional sort after GroupAggregate +explain verbose +select * from mat_m1 order by timec desc, location; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec DESC, _hyper_2_3_chunk.location + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(11 rows) + +explain verbose +select * from mat_m1 order by location, timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=0.30..66.20 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Merge Append (cost=0.30..50.71 rows=960 width=136) + Sort Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec DESC + -> Index Scan using _hyper_2_3_chunk__materialized_hypertable_2_location_timec_idx on _timescaledb_internal._hyper_2_3_chunk (cost=0.15..19.35 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_location_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..19.35 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(9 rows) + +explain verbose +select * from mat_m1 order by location, timec asc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(11 rows) + +explain verbose +select * from mat_m1 where timec > '2018-10-01' order by timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(10 rows) + +-- outer sort is used by mat_m1 for grouping. But doesn't avoid a sort after the join --- +explain verbose +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort (cost=116.97..119.51 rows=1016 width=92) + Output: l.locid, _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + Sort Key: _hyper_2_4_chunk.timec DESC + -> Hash Join (cost=28.61..66.23 rows=1016 width=92) + Output: l.locid, _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + Hash Cond: (l.locname = _hyper_2_4_chunk.location) + -> Seq Scan on public.location_tab l (cost=0.00..22.70 rows=1270 width=36) + Output: l.locid, l.locname + -> Hash (cost=26.61..26.61 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)) + -> GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(20 rows) + +explain verbose +select * from mat_m2 where timec > '2018-10-01' order by timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(10 rows) + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc ) as q limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (cost=18.17..18.22 rows=1 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision)) + -> GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(12 rows) + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc , location asc nulls first) as q limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (cost=18.17..18.22 rows=1 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision)) + -> GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location NULLS FIRST + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(12 rows) + +--plans with CTE +explain verbose +with m1 as ( +Select * from mat_m2 where timec > '2018-10-01' order by timec desc ) +select * from m1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on m1 (cost=24.48..27.14 rows=133 width=72) + Output: m1.location, m1.timec, m1.firsth, m1.lasth, m1.maxtemp, m1.mintemp + CTE m1 + -> GroupAggregate (cost=18.17..23.15 rows=133 width=72) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_6_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_6_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_6_chunk.timec, _hyper_3_6_chunk.location + -> Sort (cost=18.17..18.50 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Sort Key: _hyper_3_6_chunk.timec DESC, _hyper_3_6_chunk.location + -> Append (cost=0.15..13.48 rows=133 width=168) + -> Index Scan using _hyper_3_6_chunk__materialized_hypertable_3_timec_idx on _timescaledb_internal._hyper_3_6_chunk (cost=0.15..13.48 rows=133 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 + Index Cond: (_hyper_3_6_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) +(13 rows) + +-- should reorder mat_m1 group by only based on mat_m1 order-by +explain verbose +select * from mat_m1, mat_m2 where mat_m1.timec > '2018-10-01' and mat_m1.timec = mat_m2.timec order by mat_m1.timec desc; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (cost=114.02..123.82 rows=160 width=160) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)), _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision)) + Merge Cond: (_hyper_2_4_chunk.timec = _hyper_3_5_chunk.timec) + -> GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) + -> Sort (cost=94.22..94.72 rows=200 width=72) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, (_timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision)), (_timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision)), (_timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision)) + Sort Key: _hyper_3_5_chunk.timec DESC + -> GroupAggregate (cost=66.58..84.58 rows=200 width=72) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _timescaledb_internal.finalize_agg('first(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_3_3, NULL::double precision), _timescaledb_internal.finalize_agg('last(anyelement,"any")'::text, NULL::name, NULL::name, '{{pg_catalog,float8},{pg_catalog,timestamptz}}'::name[], _hyper_3_5_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_5_5, NULL::double precision), _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_3_5_chunk.agg_6_6, NULL::double precision) + Group Key: _hyper_3_5_chunk.timec, _hyper_3_5_chunk.location + -> Sort (cost=66.58..68.58 rows=800 width=168) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _hyper_3_5_chunk.agg_3_3, _hyper_3_5_chunk.agg_4_4, _hyper_3_5_chunk.agg_5_5, _hyper_3_5_chunk.agg_6_6 + Sort Key: _hyper_3_5_chunk.timec, _hyper_3_5_chunk.location + -> Append (cost=0.00..28.00 rows=800 width=168) + -> Seq Scan on _timescaledb_internal._hyper_3_5_chunk (cost=0.00..14.00 rows=400 width=168) + Output: _hyper_3_5_chunk.location, _hyper_3_5_chunk.timec, _hyper_3_5_chunk.agg_3_3, _hyper_3_5_chunk.agg_4_4, _hyper_3_5_chunk.agg_5_5, _hyper_3_5_chunk.agg_6_6 + -> Seq Scan on _timescaledb_internal._hyper_3_6_chunk (cost=0.00..14.00 rows=400 width=168) + Output: _hyper_3_6_chunk.location, _hyper_3_6_chunk.timec, _hyper_3_6_chunk.agg_3_3, _hyper_3_6_chunk.agg_4_4, _hyper_3_6_chunk.agg_5_5, _hyper_3_6_chunk.agg_6_6 +(27 rows) + +--should reorder only for mat_m1. +explain verbose +select * from mat_m1, regview where mat_m1.timec > '2018-10-01' and mat_m1.timec = regview.timec order by mat_m1.timec desc; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Merge Join (cost=230.64..240.44 rows=160 width=176) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision)), _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Merge Cond: (_hyper_2_4_chunk.timec = (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec))) + -> GroupAggregate (cost=19.81..25.01 rows=160 width=88) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_4_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_4_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_4_chunk.timec, _hyper_2_4_chunk.location + -> Sort (cost=19.81..20.21 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Sort Key: _hyper_2_4_chunk.timec DESC, _hyper_2_4_chunk.location + -> Append (cost=0.15..13.95 rows=160 width=136) + -> Index Scan using _hyper_2_4_chunk__materialized_hypertable_2_timec_idx on _timescaledb_internal._hyper_2_4_chunk (cost=0.15..13.95 rows=160 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 + Index Cond: (_hyper_2_4_chunk.timec > 'Mon Oct 01 00:00:00 2018 PDT'::timestamp with time zone) + -> Sort (cost=210.84..211.34 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), (min(_hyper_1_1_chunk.location)), (sum(_hyper_1_1_chunk.temperature)), (sum(_hyper_1_1_chunk.humidity)) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) DESC + -> GroupAggregate (cost=169.59..201.19 rows=200 width=88) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), min(_hyper_1_1_chunk.location), sum(_hyper_1_1_chunk.temperature), sum(_hyper_1_1_chunk.humidity) + Group Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Sort (cost=169.59..174.44 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + Sort Key: _hyper_1_1_chunk.location, (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec)) + -> Result (cost=0.00..63.65 rows=1940 width=56) + Output: _hyper_1_1_chunk.location, time_bucket('@ 1 day'::interval, _hyper_1_1_chunk.timec), _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Append (cost=0.00..39.40 rows=1940 width=56) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_1_chunk.location, _hyper_1_1_chunk.timec, _hyper_1_1_chunk.temperature, _hyper_1_1_chunk.humidity + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (cost=0.00..19.70 rows=970 width=56) + Output: _hyper_1_2_chunk.location, _hyper_1_2_chunk.timec, _hyper_1_2_chunk.temperature, _hyper_1_2_chunk.humidity +(29 rows) + +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + locid | location | timec | minl | sumt | sumh +-------+----------+------------------------------+------+------+------ + 2 | NYC | Fri Nov 02 17:00:00 2018 PDT | NYC | | + 2 | NYC | Thu Nov 01 17:00:00 2018 PDT | NYC | 30 | 25 + 2 | NYC | Wed Oct 31 17:00:00 2018 PDT | NYC | 325 | 200 +(3 rows) + +\set ECHO none +---- Run the same queries with hash agg enabled now +set enable_hashagg = true; +\set ECHO none +--- Run the queries directly on the table now +set enable_hashagg = true; +\set ECHO none +-- diff results view select and table select +:DIFF_CMD +:DIFF_CMD2 +--check if the guc works , reordering will not work +set timescaledb.enable_cagg_reorder_groupby = false; +set enable_hashagg = false; +explain verbose +select * from mat_m1 order by timec desc, location; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (cost=104.70..105.20 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, (_timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision)), (_timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision)) + Sort Key: _hyper_2_3_chunk.timec DESC, _hyper_2_3_chunk.location + -> GroupAggregate (cost=77.15..95.05 rows=200 width=88) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _timescaledb_internal.finalize_agg('min(text)'::text, 'pg_catalog'::name, 'default'::name, '{{pg_catalog,text}}'::name[], _hyper_2_3_chunk.agg_3_3, NULL::text), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_4_4, NULL::double precision), _timescaledb_internal.finalize_agg('sum(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _hyper_2_3_chunk.agg_5_5, NULL::double precision) + Group Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Sort (cost=77.15..79.55 rows=960 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + Sort Key: _hyper_2_3_chunk.timec, _hyper_2_3_chunk.location + -> Append (cost=0.00..29.60 rows=960 width=136) + -> Seq Scan on _timescaledb_internal._hyper_2_3_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_3_chunk.location, _hyper_2_3_chunk.timec, _hyper_2_3_chunk.agg_3_3, _hyper_2_3_chunk.agg_4_4, _hyper_2_3_chunk.agg_5_5 + -> Seq Scan on _timescaledb_internal._hyper_2_4_chunk (cost=0.00..14.80 rows=480 width=136) + Output: _hyper_2_4_chunk.location, _hyper_2_4_chunk.timec, _hyper_2_4_chunk.agg_3_3, _hyper_2_4_chunk.agg_4_4, _hyper_2_4_chunk.agg_5_5 +(14 rows) + diff --git a/tsl/test/sql/CMakeLists.txt b/tsl/test/sql/CMakeLists.txt index fa78ce1d1..03a72bae5 100644 --- a/tsl/test/sql/CMakeLists.txt +++ b/tsl/test/sql/CMakeLists.txt @@ -24,6 +24,7 @@ set(TEST_FILES_DEBUG set(TEST_TEMPLATES continuous_aggs_permissions.sql.in plan_gapfill.sql.in + continuous_aggs_query.sql.in ) if (CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/tsl/test/sql/continuous_aggs_query.sql.in b/tsl/test/sql/continuous_aggs_query.sql.in new file mode 100644 index 000000000..3c5211c6a --- /dev/null +++ b/tsl/test/sql/continuous_aggs_query.sql.in @@ -0,0 +1,189 @@ +-- 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. + +\c :TEST_DBNAME :ROLE_SUPERUSER +-- stop the continous aggregate background workers from interfering +SELECT _timescaledb_internal.stop_background_workers(); +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER + +\set TEST_BASE_NAME continuous_aggs_query +SELECT + format('%s/results/%s_results_view.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW", + format('%s/results/%s_results_view_hashagg.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW_HASHAGG", + format('%s/results/%s_results_table.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_TABLE" +\gset +SELECT format('\! diff %s %s', :'TEST_RESULTS_VIEW', :'TEST_RESULTS_TABLE') as "DIFF_CMD", + format('\! diff %s %s', :'TEST_RESULTS_VIEW_HASHAGG', :'TEST_RESULTS_TABLE') as "DIFF_CMD2" +\gset + +\set ON_ERROR_STOP 0 + + +CREATE TABLE conditions ( + timec TIMESTAMPTZ NOT NULL, + location TEXT NOT NULL, + temperature DOUBLE PRECISION NULL, + humidity DOUBLE PRECISION NULL + ); + +select table_name from create_hypertable( 'conditions', 'timec'); + +insert into conditions values ( '2018-01-01 09:00:00-08', 'SFO', 55, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'por', 100, 100); +insert into conditions values ( '2018-01-02 09:00:00-08', 'SFO', 65, 45); +insert into conditions values ( '2018-01-02 09:00:00-08', 'NYC', 65, 45); +insert into conditions values ( '2018-11-01 09:00:00-08', 'NYC', 45, 30); +insert into conditions values ( '2018-11-01 10:00:00-08', 'NYC', 55, 35); +insert into conditions values ( '2018-11-01 11:00:00-08', 'NYC', 65, 40); +insert into conditions values ( '2018-11-01 12:00:00-08', 'NYC', 75, 45); +insert into conditions values ( '2018-11-01 13:00:00-08', 'NYC', 85, 50); +insert into conditions values ( '2018-11-02 09:00:00-08', 'NYC', 10, 10); +insert into conditions values ( '2018-11-02 10:00:00-08', 'NYC', 20, 15); +insert into conditions values ( '2018-11-02 11:00:00-08', 'NYC', null, null); +insert into conditions values ( '2018-11-03 09:00:00-08', 'NYC', null, null); + +create table location_tab( locid integer, locname text ); +insert into location_tab values( 1, 'SFO'); +insert into location_tab values( 2, 'NYC'); +insert into location_tab values( 3, 'por'); + +create or replace view mat_m1( location, timec, minl, sumt , sumh) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by time_bucket('1day', timec), location; + +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m1; + +--test first/last +create or replace view mat_m2(location, timec, firsth, lasth, maxtemp, mintemp) +WITH ( timescaledb.continuous, timescaledb.max_interval_per_job='365 days') +as +select location, time_bucket('1day', timec), first(humidity, timec), last(humidity, timec), max(temperature), min(temperature) +from conditions +group by time_bucket('1day', timec), location; +--time that refresh assumes as now() for repeatability +SET timescaledb.current_timestamp_mock = '2018-12-31 00:00'; +REFRESH MATERIALIZED VIEW mat_m2; + +--normal view -- +create or replace view regview( location, timec, minl, sumt , sumh) +as +select location, time_bucket('1day', timec), min(location), sum(temperature),sum(humidity) +from conditions +group by location, time_bucket('1day', timec); + +set enable_hashagg = false; + +-- NO pushdown cases --- +--when we have addl. attrs in order by that are not in the +-- group by, we will still need a sort +explain verbose +select * from mat_m1 order by sumh, sumt, minl, timec ; +explain verbose +select * from regview order by timec desc; + +-- PUSHDOWN cases -- +-- all group by elts in order by , reorder group by elts to match +-- group by order +-- This should prevent an additional sort after GroupAggregate +explain verbose +select * from mat_m1 order by timec desc, location; + +explain verbose +select * from mat_m1 order by location, timec desc; + +explain verbose +select * from mat_m1 order by location, timec asc; +explain verbose +select * from mat_m1 where timec > '2018-10-01' order by timec desc; +-- outer sort is used by mat_m1 for grouping. But doesn't avoid a sort after the join --- +explain verbose +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + +explain verbose +select * from mat_m2 where timec > '2018-10-01' order by timec desc; + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc ) as q limit 1; + +explain verbose +select * from (select * from mat_m2 where timec > '2018-10-01' order by timec desc , location asc nulls first) as q limit 1; + +--plans with CTE +explain verbose +with m1 as ( +Select * from mat_m2 where timec > '2018-10-01' order by timec desc ) +select * from m1; + +-- should reorder mat_m1 group by only based on mat_m1 order-by +explain verbose +select * from mat_m1, mat_m2 where mat_m1.timec > '2018-10-01' and mat_m1.timec = mat_m2.timec order by mat_m1.timec desc; +--should reorder only for mat_m1. +explain verbose +select * from mat_m1, regview where mat_m1.timec > '2018-10-01' and mat_m1.timec = regview.timec order by mat_m1.timec desc; + +select l.locid, mat_m1.* from mat_m1 , location_tab l where timec > '2018-10-01' and l.locname = mat_m1.location order by timec desc; + +\set ECHO none +SET client_min_messages TO error; +\o :TEST_RESULTS_VIEW +select * from mat_m1 order by timec desc, location; +select * from mat_m1 order by location, timec desc; +select * from mat_m1 order by location, timec asc; +select * from mat_m1 where timec > '2018-10-01' order by timec desc; +select * from mat_m2 where timec > '2018-10-01' order by timec desc; +\o +RESET client_min_messages; +\set ECHO all + +---- Run the same queries with hash agg enabled now +set enable_hashagg = true; +\set ECHO none +SET client_min_messages TO error; +\o :TEST_RESULTS_VIEW_HASHAGG +select * from mat_m1 order by timec desc, location; +select * from mat_m1 order by location, timec desc; +select * from mat_m1 order by location, timec asc; +select * from mat_m1 where timec > '2018-10-01' order by timec desc; +select * from mat_m2 where timec > '2018-10-01' order by timec desc; +\o +RESET client_min_messages; +\set ECHO all + +--- Run the queries directly on the table now +set enable_hashagg = true; +\set ECHO none +SET client_min_messages TO error; +\o :TEST_RESULTS_TABLE +SELECT location, time_bucket('1day', timec) as timec, min(location) as minl, sum(temperature) as sumt, sum(humidity) as sumh from conditions group by time_bucket('1day', timec) , location +order by timec desc, location; +SELECT location, time_bucket('1day', timec) as timec, min(location) as minl, sum(temperature) as sumt, sum(humidity) as sumh from conditions group by time_bucket('1day', timec) , location +order by location, timec desc; +SELECT location, time_bucket('1day', timec) as timec, min(location) as minl, sum(temperature) as sumt, sum(humidity) as sumh from conditions group by time_bucket('1day', timec) , location +order by location, timec asc; +select * from (SELECT location, time_bucket('1day', timec) as timec, min(location) as minl, sum(temperature) as sumt, sum(humidity) as sumh from conditions +group by time_bucket('1day', timec) , location ) as q +where timec > '2018-10-01' order by timec desc; +--comparison for mat_m2 queries +select * from ( +select location, time_bucket('1day', timec) as timec, first(humidity, timec) firsth, last(humidity, timec) lasth, max(temperature) maxtemp, min(temperature) mintemp +from conditions +group by time_bucket('1day', timec), location) as q +where timec > '2018-10-01' order by timec desc limit 10; +\o +RESET client_min_messages; +\set ECHO all + +-- diff results view select and table select +:DIFF_CMD +:DIFF_CMD2 + +--check if the guc works , reordering will not work +set timescaledb.enable_cagg_reorder_groupby = false; +set enable_hashagg = false; +explain verbose +select * from mat_m1 order by timec desc, location;