Skip to content

Commit e877b4c

Browse files
authored
Avoid scan on hypertable relation (#9722)
It's always empty, so this scan is useless and looks misleading. The common case when all chunks are excluded was already handled, but the cases of SELECT FROM ONLY hypertable or an empty hypertable were not.
1 parent 0581a48 commit e877b4c

12 files changed

Lines changed: 410 additions & 803 deletions

src/planner/planner.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,8 +1470,8 @@ timescaledb_set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, Rang
14701470
{
14711471
ts_planner_constraint_cleanup(root, rel);
14721472
}
1473-
14741473
break;
1474+
14751475
case TS_REL_CHUNK_STANDALONE:
14761476
case TS_REL_CHUNK_CHILD:
14771477
/* Check for UPDATE/DELETE/MERGE (DML) on compressed chunks */
@@ -1482,10 +1482,14 @@ timescaledb_set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, Rang
14821482
{
14831483
ts_cm_functions->set_rel_pathlist_dml(root, rel, rti, rte, ht);
14841484
}
1485-
break;
14861485
}
1487-
TS_FALLTHROUGH;
1488-
default:
1486+
else
1487+
{
1488+
apply_optimizations(root, reltype, rel, rte, ht);
1489+
}
1490+
break;
1491+
1492+
case TS_REL_HYPERTABLE:
14891493
/*
14901494
* Set the indexlist for a hypertable parent to NIL since we
14911495
* should not try to do any index scans on hypertable parents,
@@ -1497,10 +1501,26 @@ timescaledb_set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, Rang
14971501
* This has to be after the hypertable is expanded, since the
14981502
* indexlist is used during hypertable expansion.
14991503
*/
1500-
if (reltype == TS_REL_HYPERTABLE)
1504+
1505+
rel->indexlist = NIL;
1506+
1507+
if (!rte->inh)
1508+
{
1509+
/*
1510+
* This happens with SELECT FROM ONLY hypertable or with an
1511+
* empty hypertable. Mark it as dummy, otherwise we'll get a
1512+
* scan on hypertable relation itself. It's always empty, so
1513+
* this scan is useless and looks misleading.
1514+
*/
1515+
mark_dummy_rel(rel);
1516+
}
1517+
else
15011518
{
1502-
rel->indexlist = NIL;
1519+
apply_optimizations(root, reltype, rel, rte, ht);
15031520
}
1521+
break;
1522+
1523+
default:
15041524
apply_optimizations(root, reltype, rel, rte, ht);
15051525
break;
15061526
}

test/expected/ddl.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ SELECT * FROM ONLY PUBLIC."Hypertable_1";
259259

260260
EXPLAIN (buffers off, costs off) SELECT * FROM ONLY PUBLIC."Hypertable_1";
261261
--- QUERY PLAN ---
262-
Seq Scan on "Hypertable_1"
262+
Result
263+
One-Time Filter: false
263264

264265
SELECT * FROM test.show_columns('PUBLIC."Hypertable_1"');
265266
Column | Type | NotNull

test/expected/dml_system_columns.out

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,35 +434,37 @@ VACUUM FREEZE ANALYZE ht_zero_chunks;
434434
--- QUERY PLAN ---
435435
Custom Scan (ModifyHypertable) (actual rows=0.00 loops=1)
436436
-> Update on public.ht_zero_chunks (actual rows=0.00 loops=1)
437-
-> Seq Scan on public.ht_zero_chunks (actual rows=0.00 loops=1)
437+
-> Result (actual rows=0.00 loops=1)
438438
Output: 1, ctid
439-
Filter: (ht_zero_chunks."time" = 'Wed Jan 15 00:00:00 2020 PST'::timestamp with time zone)
439+
One-Time Filter: false
440440

441441
:PREFIX DELETE FROM ht_zero_chunks WHERE time = '2020-01-15';
442442
--- QUERY PLAN ---
443443
Custom Scan (ModifyHypertable) (actual rows=0.00 loops=1)
444444
-> Delete on public.ht_zero_chunks (actual rows=0.00 loops=1)
445-
-> Seq Scan on public.ht_zero_chunks (actual rows=0.00 loops=1)
445+
-> Result (actual rows=0.00 loops=1)
446446
Output: ctid
447-
Filter: (ht_zero_chunks."time" = 'Wed Jan 15 00:00:00 2020 PST'::timestamp with time zone)
447+
One-Time Filter: false
448448

449449
:PREFIX UPDATE ht_zero_chunks SET v = 1 RETURNING ctid, xmin, tableoid::regclass, *;
450450
--- QUERY PLAN ---
451451
Custom Scan (ModifyHypertable) (actual rows=0.00 loops=1)
452452
Output: ctid, xmin, ((tableoid)::regclass), "time", v
453453
-> Update on public.ht_zero_chunks (actual rows=0.00 loops=1)
454454
Output: ctid, xmin, (tableoid)::regclass, "time", v
455-
-> Seq Scan on public.ht_zero_chunks (actual rows=0.00 loops=1)
455+
-> Result (actual rows=0.00 loops=1)
456456
Output: 1, ctid
457+
One-Time Filter: false
457458

458459
:PREFIX DELETE FROM ht_zero_chunks RETURNING ctid, xmin, tableoid::regclass, *;
459460
--- QUERY PLAN ---
460461
Custom Scan (ModifyHypertable) (actual rows=0.00 loops=1)
461462
Output: ctid, xmin, ((tableoid)::regclass), "time", v
462463
-> Delete on public.ht_zero_chunks (actual rows=0.00 loops=1)
463464
Output: ctid, xmin, (tableoid)::regclass, "time", v
464-
-> Seq Scan on public.ht_zero_chunks (actual rows=0.00 loops=1)
465+
-> Result (actual rows=0.00 loops=1)
465466
Output: ctid
467+
One-Time Filter: false
466468

467469
DROP TABLE ht_zero_chunks;
468470
-- UPDATE/DELETE on a hypertable that becomes a dummy rel due to

test/expected/plan_expand_hypertable-15.out

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3236,35 +3236,21 @@ EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10);
32363236
Subquery Scan on f_t1_2
32373237
-> Unique
32383238
-> Sort
3239-
Sort Key: j.a
3240-
-> Nested Loop
3241-
-> Seq Scan on t1 j
3242-
-> Unique
3243-
-> Index Scan using t1_b_idx on t1
3244-
Index Cond: (b = 10)
3245-
Filter: (a = j.a)
3239+
Sort Key: a
3240+
-> Result
3241+
One-Time Filter: false
32463242

32473243
EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10) sc, f_t2(sc.a, 10);
32483244
--- QUERY PLAN ---
32493245
Nested Loop
32503246
-> Unique
32513247
-> Sort
32523248
Sort Key: j.a
3253-
-> Nested Loop
3254-
-> Seq Scan on t1 j
3255-
-> Unique
3256-
-> Index Scan using t1_b_idx on t1
3257-
Index Cond: (b = 10)
3258-
Filter: (a = j.a)
3249+
-> Result
3250+
One-Time Filter: false
32593251
-> Unique
3260-
-> Nested Loop
3261-
-> Unique
3262-
-> Index Scan using t1_b_idx on t1 t1_1
3263-
Index Cond: (b = 10)
3264-
Filter: (a = t1.a)
3265-
-> Index Scan using t2_b_idx on t2 j_1
3266-
Index Cond: (b = 10)
3267-
Filter: (a = t1.a)
3252+
-> Result
3253+
One-Time Filter: false
32683254

32693255
CREATE TABLE metrics_int1(time int, device text, value float) WITH (tsdb.hypertable,tsdb.partition_column='time',tsdb.chunk_interval=1);
32703256
INSERT INTO metrics_int1 SELECT i, i::text, i FROM generate_series(3,7) i;

test/expected/plan_expand_hypertable-16.out

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3234,35 +3234,21 @@ EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10);
32343234
Subquery Scan on f_t1_2
32353235
-> Unique
32363236
-> Sort
3237-
Sort Key: j.a
3238-
-> Nested Loop
3239-
-> Seq Scan on t1 j
3240-
-> Limit
3241-
-> Index Scan using t1_b_idx on t1
3242-
Index Cond: (b = 10)
3243-
Filter: (a = j.a)
3237+
Sort Key: a
3238+
-> Result
3239+
One-Time Filter: false
32443240

32453241
EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10) sc, f_t2(sc.a, 10);
32463242
--- QUERY PLAN ---
32473243
Nested Loop
32483244
-> Unique
32493245
-> Sort
32503246
Sort Key: j.a
3251-
-> Nested Loop
3252-
-> Seq Scan on t1 j
3253-
-> Limit
3254-
-> Index Scan using t1_b_idx on t1
3255-
Index Cond: (b = 10)
3256-
Filter: (a = j.a)
3247+
-> Result
3248+
One-Time Filter: false
32573249
-> Limit
3258-
-> Nested Loop
3259-
-> Limit
3260-
-> Index Scan using t1_b_idx on t1 t1_1
3261-
Index Cond: (b = 10)
3262-
Filter: (a = t1.a)
3263-
-> Index Scan using t2_b_idx on t2 j_1
3264-
Index Cond: (b = 10)
3265-
Filter: (a = t1.a)
3250+
-> Result
3251+
One-Time Filter: false
32663252

32673253
CREATE TABLE metrics_int1(time int, device text, value float) WITH (tsdb.hypertable,tsdb.partition_column='time',tsdb.chunk_interval=1);
32683254
INSERT INTO metrics_int1 SELECT i, i::text, i FROM generate_series(3,7) i;

test/expected/plan_expand_hypertable-17.out

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3234,35 +3234,21 @@ EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10);
32343234
Subquery Scan on f_t1_2
32353235
-> Unique
32363236
-> Sort
3237-
Sort Key: j.a
3238-
-> Nested Loop
3239-
-> Seq Scan on t1 j
3240-
-> Limit
3241-
-> Index Scan using t1_b_idx on t1
3242-
Index Cond: (b = 10)
3243-
Filter: (a = j.a)
3237+
Sort Key: a
3238+
-> Result
3239+
One-Time Filter: false
32443240

32453241
EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10) sc, f_t2(sc.a, 10);
32463242
--- QUERY PLAN ---
32473243
Nested Loop
32483244
-> Unique
32493245
-> Sort
32503246
Sort Key: j.a
3251-
-> Nested Loop
3252-
-> Seq Scan on t1 j
3253-
-> Limit
3254-
-> Index Scan using t1_b_idx on t1
3255-
Index Cond: (b = 10)
3256-
Filter: (a = j.a)
3247+
-> Result
3248+
One-Time Filter: false
32573249
-> Limit
3258-
-> Nested Loop
3259-
-> Limit
3260-
-> Index Scan using t1_b_idx on t1 t1_1
3261-
Index Cond: (b = 10)
3262-
Filter: (a = t1.a)
3263-
-> Index Scan using t2_b_idx on t2 j_1
3264-
Index Cond: (b = 10)
3265-
Filter: (a = t1.a)
3250+
-> Result
3251+
One-Time Filter: false
32663252

32673253
CREATE TABLE metrics_int1(time int, device text, value float) WITH (tsdb.hypertable,tsdb.partition_column='time',tsdb.chunk_interval=1);
32683254
INSERT INTO metrics_int1 SELECT i, i::text, i FROM generate_series(3,7) i;

test/expected/plan_expand_hypertable-18.out

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3234,35 +3234,21 @@ EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10);
32343234
Subquery Scan on f_t1_2
32353235
-> Unique
32363236
-> Sort
3237-
Sort Key: j.a
3238-
-> Nested Loop
3239-
-> Seq Scan on t1 j
3240-
-> Limit
3241-
-> Index Scan using t1_b_idx on t1
3242-
Index Cond: (b = 10)
3243-
Filter: (a = j.a)
3237+
Sort Key: a
3238+
-> Result
3239+
One-Time Filter: false
32443240

32453241
EXPLAIN (buffers off, costs off) SELECT * FROM f_t1_2(10) sc, f_t2(sc.a, 10);
32463242
--- QUERY PLAN ---
32473243
Nested Loop
32483244
-> Unique
32493245
-> Sort
32503246
Sort Key: j.a
3251-
-> Nested Loop
3252-
-> Seq Scan on t1 j
3253-
-> Limit
3254-
-> Index Scan using t1_b_idx on t1
3255-
Index Cond: (b = 10)
3256-
Filter: (a = j.a)
3247+
-> Result
3248+
One-Time Filter: false
32573249
-> Limit
3258-
-> Nested Loop
3259-
-> Limit
3260-
-> Index Scan using t1_b_idx on t1 t1_1
3261-
Index Cond: (b = 10)
3262-
Filter: (a = t1.a)
3263-
-> Index Scan using t2_b_idx on t2 j_1
3264-
Index Cond: (b = 10)
3265-
Filter: (a = t1.a)
3250+
-> Result
3251+
One-Time Filter: false
32663252

32673253
CREATE TABLE metrics_int1(time int, device text, value float) WITH (tsdb.hypertable,tsdb.partition_column='time',tsdb.chunk_interval=1);
32683254
INSERT INTO metrics_int1 SELECT i, i::text, i FROM generate_series(3,7) i;

0 commit comments

Comments
 (0)