\o /dev/null \ir include/create_single_db.sql SET client_min_messages = WARNING; DROP DATABASE IF EXISTS single; SET client_min_messages = NOTICE; CREATE DATABASE single; \c single CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; psql:include/create_single_db.sql:7: NOTICE: installing required extension "postgres_fdw" SELECT setup_timescaledb(hostname => 'fakehost'); -- fakehost makes sure there is no network connection \o \ir include/sql_query_results.sql CREATE TABLE PUBLIC.hyper_1 ( time TIMESTAMP NOT NULL, series_0 DOUBLE PRECISION NULL, series_1 DOUBLE PRECISION NULL, series_2 DOUBLE PRECISION NULL ); CREATE INDEX "time_plain" ON PUBLIC.hyper_1 (time DESC, series_0); SELECT * FROM create_hypertable('"public"."hyper_1"'::regclass, 'time'::name, number_partitions => 1, chunk_size_bytes=>10000); create_hypertable ------------------- (1 row) INSERT INTO hyper_1 SELECT to_timestamp(ser), ser, ser+10000, sqrt(ser::numeric) FROM generate_series(0,10000) ser; INSERT INTO hyper_1 SELECT to_timestamp(ser), ser, ser+10000, sqrt(ser::numeric) FROM generate_series(10001,20000) ser; --non-aggregates use MergeAppend in both optimized and non-optimized EXPLAIN (costs off) SELECT * FROM hyper_1 ORDER BY "time" DESC limit 2; QUERY PLAN -------------------------------------------------------------------- Limit -> Merge Append Sort Key: _hyper_1_0_replica."time" DESC -> Sort Sort Key: _hyper_1_0_replica."time" DESC -> Seq Scan on _hyper_1_0_replica -> Sort Sort Key: _hyper_1_1_0_partition."time" DESC -> Seq Scan on _hyper_1_1_0_partition -> Index Scan using "1-time_plain" on _hyper_1_1_0_1_data -> Index Scan using "2-time_plain" on _hyper_1_1_0_2_data (11 rows) SELECT * FROM hyper_1 ORDER BY "time" DESC limit 2; time | series_0 | series_1 | series_2 --------------------------+----------+----------+------------------ Wed Dec 31 21:33:20 1969 | 20000 | 30000 | 141.42135623731 Wed Dec 31 21:33:19 1969 | 19999 | 29999 | 141.417820659208 (2 rows) --aggregates use MergeAppend only in optimized EXPLAIN (costs off) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; QUERY PLAN ------------------------------------------------------------------------------------------------------ Limit -> GroupAggregate Group Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) -> Result -> Merge Append Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Seq Scan on _hyper_1_0_replica -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_1_0_partition."time")) DESC -> Seq Scan on _hyper_1_1_0_partition -> Index Scan using "1-time_plain" on _hyper_1_1_0_1_data -> Index Scan using "2-time_plain" on _hyper_1_1_0_2_data (14 rows) --the minute and second results should be diff SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; t | avg | min | avg --------------------------+---------+-------+------------------ Wed Dec 31 21:33:00 1969 | 19990 | 29980 | 141.385994856058 Wed Dec 31 21:32:00 1969 | 19949.5 | 29920 | 141.242685621416 (2 rows) SELECT date_trunc('second', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; t | avg | min | avg --------------------------+-------+-------+------------------ Wed Dec 31 21:33:20 1969 | 20000 | 30000 | 141.42135623731 Wed Dec 31 21:33:19 1969 | 19999 | 29999 | 141.417820659208 (2 rows) --test that when index on time used by constraint, still works correctly EXPLAIN (costs off) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 WHERE time < to_timestamp(900) GROUP BY t ORDER BY t DESC LIMIT 2; QUERY PLAN ------------------------------------------------------------------------------------------------------------- Limit -> GroupAggregate Group Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) -> Result -> Merge Append Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Seq Scan on _hyper_1_0_replica Filter: ("time" < 'Wed Dec 31 16:15:00 1969 PST'::timestamp with time zone) -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_1_0_partition."time")) DESC -> Seq Scan on _hyper_1_1_0_partition Filter: ("time" < 'Wed Dec 31 16:15:00 1969 PST'::timestamp with time zone) -> Index Scan using "1-time_plain" on _hyper_1_1_0_1_data Index Cond: ("time" < 'Wed Dec 31 16:15:00 1969 PST'::timestamp with time zone) -> Index Scan using "2-time_plain" on _hyper_1_1_0_2_data Index Cond: ("time" < 'Wed Dec 31 16:15:00 1969 PST'::timestamp with time zone) (18 rows) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 WHERE time < to_timestamp(900) GROUP BY t ORDER BY t DESC LIMIT 2; t | avg | min | avg --------------------------+-------+-------+------------------ Wed Dec 31 16:14:00 1969 | 869.5 | 10840 | 29.4858228711055 Wed Dec 31 16:13:00 1969 | 809.5 | 10780 | 28.4500853206775 (2 rows) --test that still works with an expression index on data_trunc. DROP INDEX "time_plain"; CREATE INDEX "time_trunc" ON PUBLIC.hyper_1 (date_trunc('minute', time)); EXPLAIN (costs off) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; QUERY PLAN ------------------------------------------------------------------------------------------------------ Limit -> GroupAggregate Group Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) -> Result -> Merge Append Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Seq Scan on _hyper_1_0_replica -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_1_0_partition."time")) DESC -> Seq Scan on _hyper_1_1_0_partition -> Index Scan Backward using "3-time_trunc" on _hyper_1_1_0_1_data -> Index Scan Backward using "4-time_trunc" on _hyper_1_1_0_2_data (14 rows) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; t | avg | min | avg --------------------------+---------+-------+------------------ Wed Dec 31 21:33:00 1969 | 19990 | 29980 | 141.385994856058 Wed Dec 31 21:32:00 1969 | 19949.5 | 29920 | 141.242685621416 (2 rows) --test that works with both indexes CREATE INDEX "time_plain" ON PUBLIC.hyper_1 (time DESC, series_0); EXPLAIN (costs off) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; QUERY PLAN ------------------------------------------------------------------------------------------------------ Limit -> GroupAggregate Group Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) -> Result -> Merge Append Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_0_replica."time")) DESC -> Seq Scan on _hyper_1_0_replica -> Sort Sort Key: (date_trunc('minute'::text, _hyper_1_1_0_partition."time")) DESC -> Seq Scan on _hyper_1_1_0_partition -> Index Scan Backward using "3-time_trunc" on _hyper_1_1_0_1_data -> Index Scan Backward using "4-time_trunc" on _hyper_1_1_0_2_data (14 rows) SELECT date_trunc('minute', time) t, avg(series_0), min(series_1), avg(series_2) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; t | avg | min | avg --------------------------+---------+-------+------------------ Wed Dec 31 21:33:00 1969 | 19990 | 29980 | 141.385994856058 Wed Dec 31 21:32:00 1969 | 19949.5 | 29920 | 141.242685621416 (2 rows)