Modify group by clause on continuous aggr views

Reorder the group by clause to match the ordering of the
ORDER BY by clause. SELECTs on continuous aggregate queries
often have an order by clause on the time_bucket column.
If the order-by does not match the grouping clause,
the planner inserts an additional Sort node after
the view evaluation (Aggregate node).
preprocess_groupclause does this reordering if the ORDER BY clause
is part of the current subquery being processed. But when we have
a continuous aggregate view, the order by needs to be derived
from the outer query. This PR allows the order by from
outer query to propagate to group clause of continuous aggr. view.
The rewrite is :
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, a
  ) order by b;
This commit is contained in:
gayyappan 2019-11-22 15:16:25 -05:00 committed by gayyappan
parent e670090727
commit ff78290718
8 changed files with 1605 additions and 19 deletions

View File

@ -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",

View File

@ -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;

View File

@ -27,6 +27,7 @@
#include <tcop/tcopprot.h>
#include <optimizer/plancat.h>
#include <nodes/nodeFuncs.h>
#include <parser/analyze.h>
#include <catalog/pg_constraint.h>
#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)
{

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;