mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 11:03:36 +08:00
PostgreSQL 11 added support for query plans that do partitionwise aggregation on partitioned tables. Such query plans push down aggregates to individual partitions (either fully or partially) for similar or better performance than regular plans due to, among other things, improved locking. The changes in this commit adds the corresponding partitionwise aggregation functionality for hypertables. To enable this functionality on hypertables, we add partitioning metadata at the planning stage to make the regular PostgreSQL planner believe it is planning a partitioned table. Alternatively, we could have added the corresponding planner paths in our own code, e.g., in the create_upper_paths_hook, but this would require copying or re-implementing a large amount of PostgreSQL planning code. Note that partitionwise aggregation will only work with PostgreSQL 11. As a side effect of making hypertables look like partitioned tables during planning, some append plans will differ because the planner removes any Result projection nodes from such plans, knowing it can push projections down to the partitions instead. This also affects a number of query-related tests, so these have been split into version-specific tests.
48 lines
2.5 KiB
MySQL
48 lines
2.5 KiB
MySQL
-- 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.
|
|
|
|
\o /dev/null
|
|
\ir include/insert_two_partitions.sql
|
|
\o
|
|
|
|
SELECT * FROM PUBLIC."two_Partitions";
|
|
|
|
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions";
|
|
|
|
\echo "The following queries should NOT scan two_Partitions._hyper_1_1_chunk"
|
|
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE device_id = 'dev2';
|
|
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE device_id = 'dev'||'2';
|
|
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE 'dev'||'2' = device_id;
|
|
|
|
--test integer partition key
|
|
CREATE TABLE "int_part"(time timestamp, object_id int, temp float);
|
|
SELECT create_hypertable('"int_part"', 'time', 'object_id', 2);
|
|
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 1, 22.5);
|
|
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 2, 22.5);
|
|
|
|
--check that there are two chunks
|
|
SELECT * FROM test.show_subtables('int_part');
|
|
|
|
SELECT * FROM "int_part" WHERE object_id = 1;
|
|
--make sure this touches only one partititon
|
|
EXPLAIN (verbose ON, costs off) SELECT * FROM "int_part" WHERE object_id = 1;
|
|
|
|
--TODO: handle this later?
|
|
--EXPLAIN (verbose ON, costs off) SELECT * FROM "two_Partitions" WHERE device_id IN ('dev2', 'dev21');
|
|
|
|
\echo "The following shows non-aggregated queries with time desc using merge append"
|
|
EXPLAIN (verbose ON, costs off)SELECT * FROM PUBLIC."two_Partitions" ORDER BY "timeCustom" DESC NULLS LAST limit 2;
|
|
|
|
--shows that more specific indexes are used if the WHERE clauses "match", uses the series_1 index here.
|
|
EXPLAIN (verbose ON, costs off)SELECT * FROM PUBLIC."two_Partitions" WHERE series_1 IS NOT NULL ORDER BY "timeCustom" DESC NULLS LAST limit 2;
|
|
--here the "match" is implication series_1 > 1 => series_1 IS NOT NULL
|
|
EXPLAIN (verbose ON, costs off)SELECT * FROM PUBLIC."two_Partitions" WHERE series_1 > 1 ORDER BY "timeCustom" DESC NULLS LAST limit 2;
|
|
|
|
--note that without time transform things work too
|
|
EXPLAIN (verbose ON, costs off)SELECT "timeCustom" t, min(series_0) FROM PUBLIC."two_Partitions" GROUP BY t ORDER BY t DESC NULLS LAST limit 2;
|
|
|
|
--TODO: time transform doesn't work
|
|
EXPLAIN (verbose ON, costs off)SELECT "timeCustom"/10 t, min(series_0) FROM PUBLIC."two_Partitions" GROUP BY t ORDER BY t DESC NULLS LAST limit 2;
|
|
EXPLAIN (verbose ON, costs off)SELECT "timeCustom"%10 t, min(series_0) FROM PUBLIC."two_Partitions" GROUP BY t ORDER BY t DESC NULLS LAST limit 2;
|