mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-21 05:04:32 +08:00
This optimization will replace the MergeAppendPath for queries on hypertables ordered by the time partitioning column and with a LIMIT clause with an ordered AppendPath. This optimization will remove the need for last point queries to access every chunk of a hypertable. This commit also adds struct TimescaleDBPrivate which is stored in RelOptInfo->fdw_private to store TimescaleDB-specific plan state between different planner hook invocations in the plan. We needed to add TimescaleDBPrivate to store a flag indicating whether or not to use ordered append between different parts of the planner.
133 lines
3.7 KiB
SQL
133 lines
3.7 KiB
SQL
-- This file and its contents are licensed under the Apache License 2.0.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-APACHE for a copy of the license.
|
|
|
|
-- print chunks ordered by time to ensure ordering we want
|
|
SELECT
|
|
ht.table_name AS hypertable,
|
|
c.table_name AS chunk,
|
|
ds.range_start
|
|
FROM
|
|
_timescaledb_catalog.chunk c
|
|
INNER JOIN _timescaledb_catalog.chunk_constraint cc ON c.id = cc.chunk_id
|
|
INNER JOIN _timescaledb_catalog.dimension_slice ds ON ds.id=cc.dimension_slice_id
|
|
INNER JOIN _timescaledb_catalog.dimension d ON ds.dimension_id = d.id
|
|
INNER JOIN _timescaledb_catalog.hypertable ht ON d.hypertable_id = ht.id
|
|
ORDER BY ht.table_name, range_start;
|
|
|
|
-- test ASC for ordered chunks
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time ASC LIMIT 1;
|
|
|
|
-- test DESC for ordered chunks
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time DESC LIMIT 1;
|
|
|
|
-- test ASC for reverse ordered chunks
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append_reverse
|
|
ORDER BY time ASC LIMIT 1;
|
|
|
|
-- test DESC for reverse ordered chunks
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append_reverse
|
|
ORDER BY time DESC LIMIT 1;
|
|
|
|
-- test query with ORDER BY column not in targetlist
|
|
:PREFIX SELECT
|
|
device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time ASC LIMIT 1;
|
|
|
|
-- ORDER BY may include other columns after time column
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time DESC, device_id LIMIT 1;
|
|
|
|
-- queries with ORDER BY non-time column shouldn't use ordered append
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
ORDER BY device_id LIMIT 1;
|
|
|
|
-- time column must be primary sort order
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
ORDER BY device_id, time LIMIT 1;
|
|
|
|
-- queries without LIMIT shouldnt use ordered append
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time ASC;
|
|
|
|
-- queries without ORDER BY shouldnt use ordered append (still uses append though)
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
LIMIT 1;
|
|
|
|
-- test interaction with constraint exclusion
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
WHERE time > '2000-01-07'
|
|
ORDER BY time ASC LIMIT 1;
|
|
|
|
:PREFIX SELECT
|
|
time, device_id, value
|
|
FROM ordered_append
|
|
WHERE time > '2000-01-07'
|
|
ORDER BY time DESC LIMIT 1;
|
|
|
|
-- min/max queries
|
|
:PREFIX SELECT max(time) FROM ordered_append;
|
|
|
|
:PREFIX SELECT min(time) FROM ordered_append;
|
|
|
|
-- test first/last (doesn't use ordered append yet)
|
|
:PREFIX SELECT first(time, time) FROM ordered_append;
|
|
|
|
:PREFIX SELECT last(time, time) FROM ordered_append;
|
|
|
|
-- test query with time_bucket
|
|
:PREFIX SELECT
|
|
time_bucket('1d',time), device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time ASC LIMIT 1;
|
|
|
|
-- test query with order by time_bucket (should not use ordered append)
|
|
:PREFIX SELECT
|
|
time_bucket('1d',time), device_id, value
|
|
FROM ordered_append
|
|
ORDER BY 1 LIMIT 1;
|
|
|
|
-- test query with order by time_bucket (should not use ordered append)
|
|
:PREFIX SELECT
|
|
time_bucket('1d',time), device_id, value
|
|
FROM ordered_append
|
|
ORDER BY time_bucket('1d',time) LIMIT 1;
|
|
|
|
-- test query with now() should result in ordered append with constraint aware append
|
|
:PREFIX SELECT * FROM ordered_append WHERE time < now() + '1 month'
|
|
ORDER BY time DESC limit 1;
|
|
|
|
-- test CTE
|
|
:PREFIX WITH i AS (SELECT * FROM ordered_append WHERE time < now() ORDER BY time DESC limit 100)
|
|
SELECT * FROM i;
|
|
|
|
-- test LATERAL with ordered append in the outer query
|
|
:PREFIX SELECT * FROM ordered_append, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2;
|
|
|
|
-- test LATERAL with ordered append in the lateral query
|
|
:PREFIX SELECT * FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM ordered_append ORDER BY time DESC limit 2) l;
|
|
|