Skip to content

Commit 2de6b02

Browse files
committed
Add optimization to use HashAggregate more often
This optimization adds a HashAggregate plan to many group by queries. In plain postgres, many time-series queries will not use the hash aggregate because the planner will incorrectly assume that the number of rows is much larger than it actually is and will use the less efficient GroupAggregate instead of a HashAggregate to prevent running out of memory. The planner will assume a large number of rows because the statistics planner for grouping assumes that the number of distinct items produced by a function is the same as the number of distinct items going in. This is not true for functions like time_bucket and date_trunc. This optimization fixes the statistics and add the HashAggregate plan if appropriate. The statistics now rely on evaluating the spread of a variable and dividing it by the interval in the time_bucket or date_trunc. This is still an overestimate of the total number of groups but is better than before. A further improvement on this will be to evaluate the quals (WHERE clauses) on the query to try to derive a tighter spread on the variable. This is left to a future optimization.
1 parent d1a05ba commit 2de6b02

21 files changed

+2108
-54
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
|Linux/macOS|Windows|Coverity|Code Coverage|
22
|:---:|:---:|:---:|:---:|
3-
|[![Build Status](https://travis-ci.org/timescale/timescaledb.svg?branch=master)](https://travis-ci.org/timescale/timescaledb)|[![Windows build status](https://ci.appveyor.com/api/projects/status/15sqkl900t04hywu/branch/master?svg=true)](https://ci.appveyor.com/project/RobAtticus/timescaledb/branch/master)|[![Coverity Scan Build Status](https://scan.coverity.com/projects/timescale-timescaledb/badge.svg)](https://scan.coverity.com/projects/timescale-timescaledb)|[![Code Coverage](https://codecov.io/gh/timescale/timescaledb/branch/master/graphs/badge.svg?branch=master)](https://codecov.io/gh/timescale/timescaledb/branch/master/graphs/badge.svg?branch=master)
3+
|[![Build Status](https://travis-ci.org/timescale/timescaledb.svg?branch=master)](https://travis-ci.org/timescale/timescaledb)|[![Windows build status](https://ci.appveyor.com/api/projects/status/15sqkl900t04hywu/branch/master?svg=true)](https://ci.appveyor.com/project/RobAtticus/timescaledb/branch/master)|[![Coverity Scan Build Status](https://scan.coverity.com/projects/timescale-timescaledb/badge.svg)](https://scan.coverity.com/projects/timescale-timescaledb)|[![Code Coverage](https://codecov.io/gh/timescale/timescaledb/branch/master/graphs/badge.svg?branch=master)](https://codecov.io/gh/timescale/timescaledb)
44

55

66
## TimescaleDB

src/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ set(HEADERS
6868
planner_utils.h
6969
planner_import.h
7070
plan_expand_hypertable.h
71+
plan_add_hashagg.h
7172
process_utility.h
7273
scanner.h
7374
subspace_store.h
@@ -106,9 +107,10 @@ set(SOURCES
106107
init.c
107108
partitioning.c
108109
planner.c
110+
plan_expand_hypertable.c
111+
plan_add_hashagg.c
109112
planner_import.c
110113
planner_utils.c
111-
plan_expand_hypertable.c
112114
process_utility.c
113115
scanner.c
114116
sort_transform.c

src/dimension.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ hyperspace_calculate_point(Hyperspace *hs, HeapTuple tuple, TupleDesc tupdesc)
557557
NameStr(d->fd.column_name)),
558558
errhint("Columns used for time partitioning can not be NULL")));
559559

560-
p->coordinates[p->num_coords++] = time_value_to_internal(datum, d->fd.column_type);
560+
p->coordinates[p->num_coords++] = time_value_to_internal(datum, d->fd.column_type, false);
561561
}
562562
else
563563
{

src/extension.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,47 @@ extension_update_state()
111111
return extension_set_state(extension_current_state());
112112
}
113113

114+
Oid
115+
extension_schema_oid(void)
116+
{
117+
Datum result;
118+
Relation rel;
119+
SysScanDesc scandesc;
120+
HeapTuple tuple;
121+
ScanKeyData entry[1];
122+
bool is_null = true;
123+
Oid schema = InvalidOid;
124+
125+
rel = heap_open(ExtensionRelationId, AccessShareLock);
126+
127+
ScanKeyInit(&entry[0],
128+
Anum_pg_extension_extname,
129+
BTEqualStrategyNumber, F_NAMEEQ,
130+
DirectFunctionCall1(namein, CStringGetDatum(EXTENSION_NAME)));
131+
132+
scandesc = systable_beginscan(rel, ExtensionNameIndexId, true,
133+
NULL, 1, entry);
134+
135+
tuple = systable_getnext(scandesc);
136+
137+
/* We assume that there can be at most one matching tuple */
138+
if (HeapTupleIsValid(tuple))
139+
{
140+
result = heap_getattr(tuple, Anum_pg_extension_extnamespace, RelationGetDescr(rel), &is_null);
141+
142+
if (!is_null)
143+
schema = DatumGetObjectId(result);
144+
}
145+
146+
systable_endscan(scandesc);
147+
heap_close(rel, AccessShareLock);
148+
149+
if (schema == InvalidOid)
150+
elog(ERROR, "extension schema not found");
151+
return schema;
152+
}
153+
154+
114155
/*
115156
* Called upon all Relcache invalidate events.
116157
* Returns whether or not to invalidate the entire extension.

src/extension.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
bool extension_invalidate(Oid relid);
88
bool extension_is_loaded(void);
99
void extension_check_version(const char *so_version);
10+
Oid extension_schema_oid(void);
1011

1112
#endif /* TIMESCALEDB_EXTENSION_H */

src/hypertable_restrict_info.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ dimension_restrict_info_create(Dimension *d)
7272
static bool
7373
dimension_restrict_info_open_add(DimensionRestrictInfoOpen *dri, StrategyNumber strategy, Const *c)
7474
{
75-
int64 value = time_value_to_internal(c->constvalue, c->consttype);
75+
int64 value = time_value_to_internal(c->constvalue, c->consttype, false);
7676

7777
switch (strategy)
7878
{

0 commit comments

Comments
 (0)