From b613f05d3badefa8323b9b7b302a77b6fa57082a Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:42:39 +0100 Subject: [PATCH 1/7] Optimize decompression planning The EquivalenceMember lookup is the most costly part, so share it between different uses. Switch batch sorted merge to use the generic pathkey matching code. Also cache some intermediate data in the CompressionInfo struct. --- .../nodes/decompress_chunk/decompress_chunk.c | 742 +++++++++--------- .../nodes/decompress_chunk/decompress_chunk.h | 12 +- .../decompress_chunk/decompress_context.h | 2 +- tsl/src/nodes/decompress_chunk/exec.c | 2 +- tsl/src/nodes/decompress_chunk/planner.c | 4 +- 5 files changed, 398 insertions(+), 364 deletions(-) diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.c b/tsl/src/nodes/decompress_chunk/decompress_chunk.c index ac2c7873422..ec47989351c 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.c +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.c @@ -48,32 +48,31 @@ typedef struct SortInfo List *required_compressed_pathkeys; List *required_eq_classes; bool needs_sequence_num; - bool can_pushdown_sort; /* sort can be pushed below DecompressChunk */ + bool use_compressed_sort; /* sort can be pushed below DecompressChunk */ + bool use_batch_sorted_merge; bool reverse; -} SortInfo; -typedef enum MergeBatchResult -{ - MERGE_NOT_POSSIBLE, - SCAN_FORWARD, - SCAN_BACKWARD -} MergeBatchResult; + List *decompressed_sort_pathkeys; + QualCost decompressed_sort_pathkeys_cost; +} SortInfo; static RangeTblEntry *decompress_chunk_make_rte(Oid compressed_relid, LOCKMODE lockmode, Query *parse); static void create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compressed_rel, - CompressionInfo *info, SortInfo *sort_info); + const CompressionInfo *compression_info, + const SortInfo *sort_info); -static DecompressChunkPath *decompress_chunk_path_create(PlannerInfo *root, CompressionInfo *info, - int parallel_workers, - Path *compressed_path); +static DecompressChunkPath * +decompress_chunk_path_create(PlannerInfo *root, const CompressionInfo *info, Path *compressed_path); static void decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, const Chunk *chunk, RelOptInfo *chunk_rel, bool needs_sequence_num); -static SortInfo build_sortinfo(const Chunk *chunk, RelOptInfo *chunk_rel, CompressionInfo *info, - List *pathkeys); +static SortInfo build_sortinfo(PlannerInfo *root, const Chunk *chunk, RelOptInfo *chunk_rel, + const CompressionInfo *info, List *pathkeys); + +static Bitmapset *find_const_segmentby(RelOptInfo *chunk_rel, const CompressionInfo *info); static bool is_compressed_column(CompressionInfo *info, Oid type) @@ -82,8 +81,8 @@ is_compressed_column(CompressionInfo *info, Oid type) } static EquivalenceClass * -append_ec_for_seqnum(PlannerInfo *root, CompressionInfo *info, SortInfo *sort_info, Var *var, - Oid sortop, bool nulls_first) +append_ec_for_seqnum(PlannerInfo *root, const CompressionInfo *info, const SortInfo *sort_info, + Var *var, Oid sortop, bool nulls_first) { MemoryContext oldcontext = MemoryContextSwitchTo(root->planner_cxt); @@ -151,7 +150,7 @@ append_ec_for_seqnum(PlannerInfo *root, CompressionInfo *info, SortInfo *sort_in } static EquivalenceClass * -append_ec_for_metadata_col(PlannerInfo *root, CompressionInfo *info, Var *var, PathKey *pk) +append_ec_for_metadata_col(PlannerInfo *root, const CompressionInfo *info, Var *var, PathKey *pk) { MemoryContext oldcontext = MemoryContextSwitchTo(root->planner_cxt); EquivalenceMember *em = makeNode(EquivalenceMember); @@ -186,9 +185,9 @@ append_ec_for_metadata_col(PlannerInfo *root, CompressionInfo *info, Var *var, P return ec; } -static void -build_compressed_scan_pathkeys(SortInfo *sort_info, PlannerInfo *root, List *chunk_pathkeys, - CompressionInfo *info) +static List * +build_compressed_scan_pathkeys(const SortInfo *sort_info, PlannerInfo *root, List *chunk_pathkeys, + const CompressionInfo *info) { Var *var; int varattno; @@ -353,7 +352,7 @@ build_compressed_scan_pathkeys(SortInfo *sort_info, PlannerInfo *root, List *chu } } } - sort_info->required_compressed_pathkeys = required_compressed_pathkeys; + return required_compressed_pathkeys; } DecompressChunkPath * @@ -377,8 +376,14 @@ build_compressioninfo(PlannerInfo *root, const Hypertable *ht, const Chunk *chun info->chunk_rel = chunk_rel; info->chunk_rte = planner_rt_fetch(chunk_rel->relid, root); - Oid relid = ts_chunk_get_relid(chunk->fd.compressed_chunk_id, true); - info->settings = ts_compression_settings_get(relid); + FormData_chunk compressed_fd = ts_chunk_get_formdata(chunk->fd.compressed_chunk_id); + info->compressed_reloid = ts_get_relation_relid(NameStr(compressed_fd.schema_name), + NameStr(compressed_fd.table_name), + /* return_invalid = */ false); + info->compression_hypertable_reloid = + ts_hypertable_id_to_relid(compressed_fd.hypertable_id, /* return_invalid = */ false); + + info->settings = ts_compression_settings_get(info->compressed_reloid); if (chunk_rel->reloptkind == RELOPT_OTHER_MEMBER_REL) { @@ -417,6 +422,18 @@ build_compressioninfo(PlannerInfo *root, const Hypertable *ht, const Chunk *chun get_attnum(info->settings->fd.relid, COMPRESSION_COLUMN_METADATA_SEQUENCE_NUM_NAME) != InvalidAttrNumber; + info->chunk_const_segmentby = find_const_segmentby(chunk_rel, info); + + /* + * If the chunk is member of hypertable expansion or a UNION, find its + * parent relation ids. We will use it later to filter out some parameterized + * paths. + */ + if (chunk_rel->reloptkind == RELOPT_OTHER_MEMBER_REL) + { + info->parent_relids = find_childrel_parents(root, chunk_rel); + } + return info; } @@ -457,11 +474,65 @@ smoothstep(double x, double start, double end) } /* - * Calculate the costs for retrieving the decompressed in-order using - * a binary heap. + * If the query 'order by' is prefix of the compression 'order by' (or equal), we can exploit + * the ordering of the individual batches to create a total ordered result without resorting + * the tuples. This speeds up all queries that use this ordering (because no sort node is + * needed). In particular, queries that use a LIMIT are speed-up because only the top elements + * of the affected batches needs to be decompressed. Without the optimization, the entire batches + * are decompressed, sorted, and then the top elements are taken from the result. + * + * The idea is to do something similar to the MergeAppend node; a BinaryHeap is used + * to merge the per segment by column sorted individual batches into a sorted result. So, we end + * up which a data flow which looks as follows: + * + * DecompressChunk + * * Decompress Batch 1 + * * Decompress Batch 2 + * * Decompress Batch 3 + * [....] + * * Decompress Batch N + * + * Using the presorted batches, we are able to open these batches dynamically. If we don't presort + * them, we would have to open all batches at the same time. This would be similar to the work the + * MergeAppend does, but this is not needed in our case and we could reduce the size of the heap and + * the amount of parallel open batches. + * + * The algorithm works as follows: + * + * (1) A sort node is placed below the decompress scan node and on top of the scan + * on the compressed chunk. This sort node uses the min/max values of the 'order by' + * columns from the metadata of the batch to get them into an order which can be + * used to merge them. + * + * [Scan on compressed chunk] -> [Sort on min/max values] -> [Decompress and merge] + * + * For example, the batches are sorted on the min value of the 'order by' metadata + * column: [0, 3] [0, 5] [3, 7] [6, 10] + * + * (2) The decompress chunk node initializes a binary heap, opens the first batch and + * decompresses the first tuple from the batch. The tuple is put on the heap. In addition + * the opened batch is marked as the most recent batch (MRB). + * + * (3) As soon as a tuple is requested from the heap, the following steps are performed: + * (3a) If the heap is empty, we are done. + * (3b) The top tuple from the heap is taken. It is checked if this tuple is from the + * MRB. If this is the case, the next batch is opened, the first tuple is decompressed, + * placed on the heap and this batch is marked as MRB. This is repeated until the + * top tuple from the heap is not from the MRB. After the top tuple is not from the + * MRB, all batches (and one ahead) which might contain the most recent tuple are + * opened and placed on the heap. + * + * In the example above, the first three batches are opened because the first two + * batches might contain tuples with a value of 0. + * (3c) The top element from the heap is removed, the next tuple from the batch is + * decompressed (if present) and placed on the heap. + * (3d) The former top tuple of the heap is returned. + * + * This function calculate the costs for retrieving the decompressed in-order + * using a binary heap. */ static void -cost_batch_sorted_merge(PlannerInfo *root, CompressionInfo *compression_info, +cost_batch_sorted_merge(PlannerInfo *root, const CompressionInfo *compression_info, DecompressChunkPath *dcpath, Path *compressed_path) { Path sort_path; /* dummy for result of cost_sort */ @@ -577,149 +648,6 @@ cost_batch_sorted_merge(PlannerInfo *root, CompressionInfo *compression_info, dcpath->custom_path.path.rows * uncompressed_row_cost; } -/* - * If the query 'order by' is prefix of the compression 'order by' (or equal), we can exploit - * the ordering of the individual batches to create a total ordered result without resorting - * the tuples. This speeds up all queries that use this ordering (because no sort node is - * needed). In particular, queries that use a LIMIT are speed-up because only the top elements - * of the affected batches needs to be decompressed. Without the optimization, the entire batches - * are decompressed, sorted, and then the top elements are taken from the result. - * - * The idea is to do something similar to the MergeAppend node; a BinaryHeap is used - * to merge the per segment by column sorted individual batches into a sorted result. So, we end - * up which a data flow which looks as follows: - * - * DecompressChunk - * * Decompress Batch 1 - * * Decompress Batch 2 - * * Decompress Batch 3 - * [....] - * * Decompress Batch N - * - * Using the presorted batches, we are able to open these batches dynamically. If we don't presort - * them, we would have to open all batches at the same time. This would be similar to the work the - * MergeAppend does, but this is not needed in our case and we could reduce the size of the heap and - * the amount of parallel open batches. - * - * The algorithm works as follows: - * - * (1) A sort node is placed below the decompress scan node and on top of the scan - * on the compressed chunk. This sort node uses the min/max values of the 'order by' - * columns from the metadata of the batch to get them into an order which can be - * used to merge them. - * - * [Scan on compressed chunk] -> [Sort on min/max values] -> [Decompress and merge] - * - * For example, the batches are sorted on the min value of the 'order by' metadata - * column: [0, 3] [0, 5] [3, 7] [6, 10] - * - * (2) The decompress chunk node initializes a binary heap, opens the first batch and - * decompresses the first tuple from the batch. The tuple is put on the heap. In addition - * the opened batch is marked as the most recent batch (MRB). - * - * (3) As soon as a tuple is requested from the heap, the following steps are performed: - * (3a) If the heap is empty, we are done. - * (3b) The top tuple from the heap is taken. It is checked if this tuple is from the - * MRB. If this is the case, the next batch is opened, the first tuple is decompressed, - * placed on the heap and this batch is marked as MRB. This is repeated until the - * top tuple from the heap is not from the MRB. After the top tuple is not from the - * MRB, all batches (and one ahead) which might contain the most recent tuple are - * opened and placed on the heap. - * - * In the example above, the first three batches are opened because the first two - * batches might contain tuples with a value of 0. - * (3c) The top element from the heap is removed, the next tuple from the batch is - * decompressed (if present) and placed on the heap. - * (3d) The former top tuple of the heap is returned. - * - * This function checks if the compression 'order by' and the query 'order by' are - * compatible and the optimization can be used. - */ -static MergeBatchResult -can_batch_sorted_merge(PlannerInfo *root, CompressionInfo *info, const Chunk *chunk) -{ - PathKey *pk; - Var *var; - Expr *expr; - char *column_name; - List *pathkeys = root->query_pathkeys; - MergeBatchResult merge_result = SCAN_FORWARD; - - /* Ensure that we have path keys and the chunk is ordered */ - if (pathkeys == NIL || ts_chunk_is_unordered(chunk)) - return MERGE_NOT_POSSIBLE; - - int nkeys = list_length(pathkeys); - - /* - * Loop over the pathkeys of the query. These pathkeys need to match the - * configured compress_orderby pathkeys. - */ - for (int pk_index = 0; pk_index < nkeys; pk_index++) - { - pk = list_nth(pathkeys, pk_index); - expr = find_em_expr_for_rel(pk->pk_eclass, info->chunk_rel); - - if (expr == NULL || !IsA(expr, Var)) - return MERGE_NOT_POSSIBLE; - - var = castNode(Var, expr); - - if (var->varattno <= 0) - return MERGE_NOT_POSSIBLE; - - column_name = get_attname(info->chunk_rte->relid, var->varattno, false); - int16 orderby_index = ts_array_position(info->settings->fd.orderby, column_name); - - if (orderby_index != pk_index + 1) - return MERGE_NOT_POSSIBLE; - - /* Check order, if the order of the first column do not match, switch to backward scan */ - Assert(pk->pk_strategy == BTLessStrategyNumber || - pk->pk_strategy == BTGreaterStrategyNumber); - - bool orderby_desc = - ts_array_get_element_bool(info->settings->fd.orderby_desc, orderby_index); - bool orderby_nullsfirst = - ts_array_get_element_bool(info->settings->fd.orderby_nullsfirst, orderby_index); - - if (pk->pk_strategy != BTLessStrategyNumber) - { - /* Test that ORDER BY and NULLS first/last do match in forward scan */ - if (orderby_desc && orderby_nullsfirst == pk->pk_nulls_first && - merge_result == SCAN_FORWARD) - continue; - /* Exact opposite in backward scan */ - else if (!orderby_desc && orderby_nullsfirst != pk->pk_nulls_first && - merge_result == SCAN_BACKWARD) - continue; - /* Switch scan direction on exact opposite order for first attribute */ - else if (!orderby_desc && orderby_nullsfirst != pk->pk_nulls_first && pk_index == 0) - merge_result = SCAN_BACKWARD; - else - return MERGE_NOT_POSSIBLE; - } - else - { - /* Test that ORDER BY and NULLS first/last do match in forward scan */ - if (!orderby_desc && orderby_nullsfirst == pk->pk_nulls_first && - merge_result == SCAN_FORWARD) - continue; - /* Exact opposite in backward scan */ - else if (orderby_desc && orderby_nullsfirst != pk->pk_nulls_first && - merge_result == SCAN_BACKWARD) - continue; - /* Switch scan direction on exact opposite order for first attribute */ - else if (orderby_desc && orderby_nullsfirst != pk->pk_nulls_first && pk_index == 0) - merge_result = SCAN_BACKWARD; - else - return MERGE_NOT_POSSIBLE; - } - } - - return merge_result; -} - /* * This function adds per-chunk sorted paths for compressed chunks if beneficial. This has two * advantages: @@ -745,63 +673,45 @@ can_batch_sorted_merge(PlannerInfo *root, CompressionInfo *info, const Chunk *ch * directly under the gather (merge) node and the per-chunk sorting are not used in parallel plans. * To save planning time, we therefore refrain from adding them. */ -static void -add_chunk_sorted_paths(PlannerInfo *root, RelOptInfo *chunk_rel, const Hypertable *ht, - Index ht_relid, Path *path, Path *compressed_path) +static Path * +make_chunk_sorted_path(PlannerInfo *root, RelOptInfo *chunk_rel, Path *path, Path *compressed_path, + const SortInfo *sort_info) { - if (root->query_pathkeys == NIL) - return; + /* + * Don't have a useful sorting after decompression. + */ + if (sort_info->decompressed_sort_pathkeys == NIL) + { + return NULL; + } /* We are only interested in regular (i.e., non index) paths */ if (!IsA(compressed_path, Path)) - return; - - /* Copy the decompress chunk path because the original can be recycled in add_path, and our - * sorted path must be independent. */ - if (!ts_is_decompress_chunk_path(path)) - return; - - DecompressChunkPath *decompress_chunk_path = - copy_decompress_chunk_path((DecompressChunkPath *) path); - - /* Iterate over the sort_pathkeys and generate all possible useful sorting */ - List *useful_pathkeys = NIL; - ListCell *lc; - foreach (lc, root->query_pathkeys) { - PathKey *pathkey = (PathKey *) lfirst(lc); - EquivalenceClass *pathkey_ec = pathkey->pk_eclass; - - if (pathkey_ec->ec_has_volatile) - return; + return NULL; + } - Expr *em_expr = find_em_expr_for_rel(pathkey_ec, chunk_rel); + Assert(ts_is_decompress_chunk_path(path)); - /* No em expression found for our rel */ - if (!em_expr) - return; + /* + * We should be given an unsorted DecompressChunk path. + */ + Assert(path->pathkeys == NIL); - /* We are only interested in sorting if this is a var */ - if (!IsA(em_expr, Var)) - return; + /* + * Create the sorted path for these useful_pathkeys. Copy the decompress + * chunk path because the original can be recycled in add_path, and our + * sorted path must be independent. + */ + DecompressChunkPath *path_copy = copy_decompress_chunk_path((DecompressChunkPath *) path); - useful_pathkeys = lappend(useful_pathkeys, pathkey); + Path *sorted_path = (Path *) create_sort_path(root, + chunk_rel, + (Path *) path_copy, + sort_info->decompressed_sort_pathkeys, + root->limit_tuples); - /* Create the sorted path for these useful_pathkeys */ - if (!pathkeys_contained_in(useful_pathkeys, - decompress_chunk_path->custom_path.path.pathkeys)) - { - Path *sorted_path = - (Path *) create_sort_path(root, - chunk_rel, - &decompress_chunk_path->custom_path.path, - list_copy(useful_pathkeys), /* useful_pathkeys is modified - in each iteration */ - root->limit_tuples); - - add_path(chunk_rel, sorted_path); - } - } + return sorted_path; } #define IS_UPDL_CMD(parse) \ @@ -846,7 +756,8 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con (compression_info->chunk_rel->reloptkind == RELOPT_BASEREL && ts_rte_is_marked_for_expansion(compression_info->chunk_rte))); - SortInfo sort_info = build_sortinfo(chunk, chunk_rel, compression_info, root->query_pathkeys); + SortInfo sort_info = + build_sortinfo(root, chunk, chunk_rel, compression_info, root->query_pathkeys); Assert(chunk->fd.compressed_chunk_id > 0); @@ -861,6 +772,16 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con chunk, chunk_rel, sort_info.needs_sequence_num); + + if (sort_info.use_compressed_sort) + { + sort_info.required_compressed_pathkeys = + build_compressed_scan_pathkeys(&sort_info, + root, + root->query_pathkeys, + compression_info); + } + compressed_rel = compression_info->compressed_rel; compressed_rel->consider_parallel = chunk_rel->consider_parallel; @@ -972,7 +893,7 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con } Path *chunk_path = - (Path *) decompress_chunk_path_create(root, compression_info, 0, compressed_path); + (Path *) decompress_chunk_path_create(root, compression_info, compressed_path); /* * Create a path for the batch sorted merge optimization. This optimization performs a @@ -982,38 +903,33 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con * directly consumed in this order and we don't need to use this optimization. */ DecompressChunkPath *batch_merge_path = NULL; - - if (ts_guc_enable_decompression_sorted_merge && !sort_info.can_pushdown_sort) + if (sort_info.use_batch_sorted_merge) { - MergeBatchResult merge_result = can_batch_sorted_merge(root, compression_info, chunk); - if (merge_result != MERGE_NOT_POSSIBLE) - { - batch_merge_path = copy_decompress_chunk_path((DecompressChunkPath *) chunk_path); + batch_merge_path = copy_decompress_chunk_path((DecompressChunkPath *) chunk_path); - batch_merge_path->reverse = (merge_result != SCAN_FORWARD); - batch_merge_path->batch_sorted_merge = true; + batch_merge_path->reverse = sort_info.reverse; + batch_merge_path->batch_sorted_merge = true; - /* The segment by optimization is only enabled if it can deliver the tuples in the - * same order as the query requested it. So, we can just copy the pathkeys of the - * query here. - */ - batch_merge_path->custom_path.path.pathkeys = root->query_pathkeys; - cost_batch_sorted_merge(root, compression_info, batch_merge_path, compressed_path); + /* The segment by optimization is only enabled if it can deliver the tuples in the + * same order as the query requested it. So, we can just copy the pathkeys of the + * query here. + */ + batch_merge_path->custom_path.path.pathkeys = root->query_pathkeys; + cost_batch_sorted_merge(root, compression_info, batch_merge_path, compressed_path); - /* If the chunk is partially compressed, prepare the path only and add it later - * to a merge append path when we are able to generate the ordered result for the - * compressed and uncompressed part of the chunk. - */ - if (!consider_partial) - add_path(chunk_rel, &batch_merge_path->custom_path.path); - } + /* If the chunk is partially compressed, prepare the path only and add it later + * to a merge append path when we are able to generate the ordered result for the + * compressed and uncompressed part of the chunk. + */ + if (!consider_partial) + add_path(chunk_rel, &batch_merge_path->custom_path.path); } /* If we can push down the sort below the DecompressChunk node, we set the pathkeys of * the decompress node to the query pathkeys, while remembering the compressed_pathkeys * corresponding to those query_pathkeys. We will determine whether to put a sort * between the decompression node and the scan during plan creation */ - if (sort_info.can_pushdown_sort) + if (sort_info.use_compressed_sort) { DecompressChunkPath *path_copy = copy_decompress_chunk_path((DecompressChunkPath *) chunk_path); @@ -1123,7 +1039,15 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con } /* Add useful sorted versions of the decompress path */ - add_chunk_sorted_paths(root, chunk_rel, ht, ht_relid, chunk_path, compressed_path); + if (chunk_path->pathkeys == NIL) + { + Path *sorted = + make_chunk_sorted_path(root, chunk_rel, chunk_path, compressed_path, &sort_info); + if (sorted != NULL) + { + add_path(chunk_rel, sorted); + } + } /* this has to go after the path is copied for the ordered path since path can get freed * in add_path */ @@ -1150,10 +1074,7 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con * If this is a partially compressed chunk we have to combine data * from compressed and uncompressed chunk. */ - path = (Path *) decompress_chunk_path_create(root, - compression_info, - compressed_path->parallel_workers, - compressed_path); + path = (Path *) decompress_chunk_path_create(root, compression_info, compressed_path); if (consider_partial) { @@ -1797,24 +1718,19 @@ decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, const RelOptInfo *chunk_rel, bool needs_sequence_num) { Index compressed_index = root->simple_rel_array_size; - FormData_chunk compressed_fd = ts_chunk_get_formdata(chunk->fd.compressed_chunk_id); - Oid compressed_reloid = ts_get_relation_relid(NameStr(compressed_fd.schema_name), - NameStr(compressed_fd.table_name), - /* return_invalid = */ false); /* * Add the compressed chunk to the baserel cache. Note that it belongs to * a different hypertable, the internal compression table. */ - Oid compression_hypertable_reloid = - ts_hypertable_id_to_relid(compressed_fd.hypertable_id, /* return_invalid = */ false); - ts_add_baserel_cache_entry_for_chunk(compressed_reloid, - ts_planner_get_hypertable(compression_hypertable_reloid, - CACHE_FLAG_NONE)); + ts_add_baserel_cache_entry_for_chunk( + info->compressed_reloid, + ts_planner_get_hypertable(info->compression_hypertable_reloid, CACHE_FLAG_NONE)); expand_planner_arrays(root, 1); - info->compressed_rte = - decompress_chunk_make_rte(compressed_reloid, info->chunk_rte->rellockmode, root->parse); + info->compressed_rte = decompress_chunk_make_rte(info->compressed_reloid, + info->chunk_rte->rellockmode, + root->parse); root->simple_rte_array[compressed_index] = info->compressed_rte; root->parse->rtable = lappend(root->parse->rtable, info->compressed_rte); @@ -1869,8 +1785,7 @@ decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, const } static DecompressChunkPath * -decompress_chunk_path_create(PlannerInfo *root, CompressionInfo *info, int parallel_workers, - Path *compressed_path) +decompress_chunk_path_create(PlannerInfo *root, const CompressionInfo *info, Path *compressed_path) { DecompressChunkPath *path; @@ -1909,9 +1824,10 @@ decompress_chunk_path_create(PlannerInfo *root, CompressionInfo *info, int paral * in a parallel plan we only set parallel_safe to true * when parallel_workers is greater than 0 which is only * the case when creating partial paths. */ - path->custom_path.path.parallel_safe = parallel_workers > 0; - path->custom_path.path.parallel_workers = parallel_workers; path->custom_path.path.parallel_aware = false; + path->custom_path.path.parallel_safe = + info->chunk_rel->consider_parallel && compressed_path->parallel_safe; + path->custom_path.path.parallel_workers = compressed_path->parallel_workers; path->custom_path.custom_paths = list_make1(compressed_path); path->reverse = false; @@ -1926,8 +1842,8 @@ decompress_chunk_path_create(PlannerInfo *root, CompressionInfo *info, int paral */ static void -create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compressed_rel, CompressionInfo *info, - SortInfo *sort_info) +create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compressed_rel, + const CompressionInfo *compression_info, const SortInfo *sort_info) { Path *compressed_path; @@ -1976,7 +1892,7 @@ create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compressed_rel, Comp bool old_bitmapscan = enable_bitmapscan; enable_bitmapscan = false; - if (sort_info->can_pushdown_sort) + if (sort_info->use_compressed_sort) { /* * If we can push down sort below decompression we temporarily switch @@ -1985,8 +1901,7 @@ create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compressed_rel, Comp */ List *orig_pathkeys = root->query_pathkeys; List *orig_eq_classes = root->eq_classes; - Bitmapset *orig_eclass_indexes = info->compressed_rel->eclass_indexes; - build_compressed_scan_pathkeys(sort_info, root, root->query_pathkeys, info); + Bitmapset *orig_eclass_indexes = compression_info->compressed_rel->eclass_indexes; root->query_pathkeys = sort_info->required_compressed_pathkeys; /* We can optimize iterating over EquivalenceClasses by reducing them to @@ -1996,24 +1911,24 @@ create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compressed_rel, Comp * * Clauseless joins work fine since they don't rely on eclass_indexes. */ - if (!info->chunk_rel->has_eclass_joins) + if (!compression_info->chunk_rel->has_eclass_joins) { int i = -1; List *required_eq_classes = NIL; - while ((i = bms_next_member(info->compressed_rel->eclass_indexes, i)) >= 0) + while ((i = bms_next_member(compression_info->compressed_rel->eclass_indexes, i)) >= 0) { EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i); required_eq_classes = lappend(required_eq_classes, cur_ec); } root->eq_classes = required_eq_classes; - info->compressed_rel->eclass_indexes = NULL; + compression_info->compressed_rel->eclass_indexes = NULL; } check_index_predicates(root, compressed_rel); create_index_paths(root, compressed_rel); root->query_pathkeys = orig_pathkeys; root->eq_classes = orig_eq_classes; - info->compressed_rel->eclass_indexes = orig_eclass_indexes; + compression_info->compressed_rel->eclass_indexes = orig_eclass_indexes; } else { @@ -2091,8 +2006,8 @@ decompress_chunk_make_rte(Oid compressed_relid, LOCKMODE lockmode, Query *parse) * This will detect Var = Const and Var = Param and set the corresponding bit * in CompressionInfo->chunk_const_segmentby. */ -static void -find_const_segmentby(RelOptInfo *chunk_rel, CompressionInfo *info) +static Bitmapset * +find_const_segmentby(RelOptInfo *chunk_rel, const CompressionInfo *info) { Bitmapset *segmentby_columns = NULL; @@ -2141,7 +2056,103 @@ find_const_segmentby(RelOptInfo *chunk_rel, CompressionInfo *info) } } } - info->chunk_const_segmentby = segmentby_columns; + + return segmentby_columns; +} + +/* + * Returns whether the pathkeys starting at the given offset match the compression + * orderby, and whether the order is reverse. + */ +static bool +match_pathkeys_to_compression_orderby(List *pathkeys, List *chunk_em_exprs, + int starting_pathkey_offset, + const CompressionInfo *compression_info, bool *out_reverse) +{ + int compressed_pk_index = 0; + for (int i = starting_pathkey_offset; i < list_length(pathkeys); i++) + { + compressed_pk_index++; + PathKey *pk = list_nth_node(PathKey, pathkeys, i); + Expr *expr = (Expr *) list_nth(chunk_em_exprs, i); + + if (expr == NULL || !IsA(expr, Var)) + { + return false; + } + + Var *var = castNode(Var, expr); + + if (var->varattno <= 0) + { + return false; + } + + char *column_name = get_attname(compression_info->chunk_rte->relid, var->varattno, false); + int orderby_index = ts_array_position(compression_info->settings->fd.orderby, column_name); + + if (orderby_index != compressed_pk_index) + { + return false; + } + + bool orderby_desc = + ts_array_get_element_bool(compression_info->settings->fd.orderby_desc, orderby_index); + bool orderby_nullsfirst = + ts_array_get_element_bool(compression_info->settings->fd.orderby_nullsfirst, + orderby_index); + + /* + * pk_strategy is either BTLessStrategyNumber (for ASC) or + * BTGreaterStrategyNumber (for DESC) + */ + bool this_pathkey_reverse = false; + if (pk->pk_strategy == BTLessStrategyNumber) + { + if (!orderby_desc && orderby_nullsfirst == pk->pk_nulls_first) + { + this_pathkey_reverse = false; + } + else if (orderby_desc && orderby_nullsfirst != pk->pk_nulls_first) + { + this_pathkey_reverse = true; + } + else + { + return false; + } + } + else if (pk->pk_strategy == BTGreaterStrategyNumber) + { + if (orderby_desc && orderby_nullsfirst == pk->pk_nulls_first) + { + this_pathkey_reverse = false; + } + else if (!orderby_desc && orderby_nullsfirst != pk->pk_nulls_first) + { + this_pathkey_reverse = true; + } + else + { + return false; + } + } + + /* + * first pathkey match determines if this is forward or backward scan + * any further pathkey items need to have same direction + */ + if (compressed_pk_index == 1) + { + *out_reverse = this_pathkey_reverse; + } + else if (this_pathkey_reverse != *out_reverse) + { + return false; + } + } + + return true; } /* @@ -2155,21 +2166,73 @@ find_const_segmentby(RelOptInfo *chunk_rel, CompressionInfo *info) * If query pathkeys is shorter than segmentby + compress_orderby pushdown can still be done */ static SortInfo -build_sortinfo(const Chunk *chunk, RelOptInfo *chunk_rel, CompressionInfo *info, List *pathkeys) +build_sortinfo(PlannerInfo *root, const Chunk *chunk, RelOptInfo *chunk_rel, + const CompressionInfo *compression_info, List *pathkeys) { - int pk_index; - PathKey *pk; Var *var; - Expr *expr; char *column_name; - ListCell *lc = list_head(pathkeys); - SortInfo sort_info = { .can_pushdown_sort = false, .needs_sequence_num = false }; + ListCell *lc; + SortInfo sort_info = { 0 }; + + if (pathkeys == NIL) + { + return sort_info; + } + + /* + * Translate the pathkeys to chunk expressions, creating a List of them + * parallel to the pathkeys list, with NULL entries if we didn't find a + * match. + */ + List *chunk_em_exprs = NIL; + foreach (lc, pathkeys) + { + PathKey *pk = lfirst(lc); + EquivalenceClass *ec = pk->pk_eclass; + Expr *em_expr = NULL; + if (!ec->ec_has_volatile) + { + em_expr = find_em_expr_for_rel(pk->pk_eclass, compression_info->chunk_rel); + } + chunk_em_exprs = lappend(chunk_em_exprs, em_expr); + } + Assert(list_length(chunk_em_exprs) == list_length(pathkeys)); + + /* Find the pathkeys we can use for explicitly sorting after decompression. */ + List *sort_pathkey_exprs = NIL; + List *sort_pathkeys = NIL; + for (int i = 0; i < list_length(chunk_em_exprs); i++) + { + PathKey *pk = list_nth_node(PathKey, pathkeys, i); + Expr *chunk_em_expr = (Expr *) list_nth(chunk_em_exprs, i); + if (chunk_em_expr == NULL) + { + break; + } - if (pathkeys == NIL || ts_chunk_is_unordered(chunk)) + sort_pathkeys = lappend(sort_pathkeys, pk); + sort_pathkey_exprs = lappend(sort_pathkey_exprs, chunk_em_expr); + } + + if (sort_pathkeys == NIL) + { + return sort_info; + } + + sort_info.decompressed_sort_pathkeys = sort_pathkeys; + cost_qual_eval(&sort_info.decompressed_sort_pathkeys_cost, sort_pathkey_exprs, root); + + /* + * Next, check if we can push the sort down to the uncompressed part. + * + * Not possible if the chunk is unordered. + */ + if (ts_chunk_is_unordered(chunk)) return sort_info; /* all segmentby columns need to be prefix of pathkeys */ - if (info->num_segmentby_columns > 0) + int i = 0; + if (compression_info->num_segmentby_columns > 0) { Bitmapset *segmentby_columns; @@ -2177,19 +2240,18 @@ build_sortinfo(const Chunk *chunk, RelOptInfo *chunk_rel, CompressionInfo *info, * initialize segmentby with equality constraints from baserestrictinfo because * those columns dont need to be prefix of pathkeys */ - find_const_segmentby(chunk_rel, info); - segmentby_columns = bms_copy(info->chunk_const_segmentby); + segmentby_columns = bms_copy(compression_info->chunk_const_segmentby); /* * loop over pathkeys until we find one that is not a segmentby column * we keep looping even if we found all segmentby columns in case a * columns appears both in baserestrictinfo and in ORDER BY clause */ - for (; lc != NULL; lc = lnext(pathkeys, lc)) + for (i = 0; i < list_length(pathkeys); i++) { - Assert(bms_num_members(segmentby_columns) <= info->num_segmentby_columns); - pk = lfirst(lc); - expr = find_em_expr_for_rel(pk->pk_eclass, info->chunk_rel); + Assert(bms_num_members(segmentby_columns) <= compression_info->num_segmentby_columns); + + Expr *expr = (Expr *) list_nth(chunk_em_exprs, i); if (expr == NULL || !IsA(expr, Var)) break; @@ -2198,94 +2260,62 @@ build_sortinfo(const Chunk *chunk, RelOptInfo *chunk_rel, CompressionInfo *info, if (var->varattno <= 0) break; - column_name = get_attname(info->chunk_rte->relid, var->varattno, false); - if (!ts_array_is_member(info->settings->fd.segmentby, column_name)) + column_name = get_attname(compression_info->chunk_rte->relid, var->varattno, false); + if (!ts_array_is_member(compression_info->settings->fd.segmentby, column_name)) break; segmentby_columns = bms_add_member(segmentby_columns, var->varattno); } /* - * if pathkeys still has items but we didn't find all segmentby columns - * we cannot push down sort + * If pathkeys still has items, but we didn't find all segmentby columns, + * we cannot satisfy these pathkeys by sorting the compressed chunk table. */ - if (lc != NULL && bms_num_members(segmentby_columns) != info->num_segmentby_columns) + if (i != list_length(pathkeys) && + bms_num_members(segmentby_columns) != compression_info->num_segmentby_columns) + { + /* + * If we didn't have any segmentby columns in pathkeys, try batch sorted merge + * instead. + */ + if (ts_guc_enable_decompression_sorted_merge && i == 0) + { + sort_info.use_batch_sorted_merge = + match_pathkeys_to_compression_orderby(pathkeys, + chunk_em_exprs, + /* starting_pathkey_offset = */ 0, + compression_info, + &sort_info.reverse); + } return sort_info; + } + } + + if (i == list_length(pathkeys)) + { + /* + * Pathkeys satisfied by sorting the compressed data on segmentby columns. + */ + sort_info.use_compressed_sort = true; + return sort_info; } /* - * if pathkeys includes columns past segmentby columns - * we need sequence_num in the targetlist for ordering + * Pathkeys includes columns past segmentby columns, so we need sequence_num + * in the targetlist for ordering. */ - if (lc != NULL) - sort_info.needs_sequence_num = true; + sort_info.needs_sequence_num = true; /* * loop over the rest of pathkeys * this needs to exactly match the configured compress_orderby */ - for (pk_index = 1; lc != NULL; lc = lnext(pathkeys, lc), pk_index++) - { - bool reverse = false; - pk = lfirst(lc); - expr = find_em_expr_for_rel(pk->pk_eclass, info->chunk_rel); - - if (expr == NULL || !IsA(expr, Var)) - return sort_info; - - var = castNode(Var, expr); - - if (var->varattno <= 0) - return sort_info; - - column_name = get_attname(info->chunk_rte->relid, var->varattno, false); - int orderby_index = ts_array_position(info->settings->fd.orderby, column_name); - - if (orderby_index != pk_index) - return sort_info; - - bool orderby_desc = - ts_array_get_element_bool(info->settings->fd.orderby_desc, orderby_index); - bool orderby_nullsfirst = - ts_array_get_element_bool(info->settings->fd.orderby_nullsfirst, orderby_index); - - /* - * pk_strategy is either BTLessStrategyNumber (for ASC) or - * BTGreaterStrategyNumber (for DESC) - */ - if (pk->pk_strategy == BTLessStrategyNumber) - { - if (!orderby_desc && orderby_nullsfirst == pk->pk_nulls_first) - reverse = false; - else if (orderby_desc && orderby_nullsfirst != pk->pk_nulls_first) - reverse = true; - else - return sort_info; - } - else if (pk->pk_strategy == BTGreaterStrategyNumber) - { - if (orderby_desc && orderby_nullsfirst == pk->pk_nulls_first) - reverse = false; - else if (!orderby_desc && orderby_nullsfirst != pk->pk_nulls_first) - reverse = true; - else - return sort_info; - } - - /* - * first pathkey match determines if this is forward or backward scan - * any further pathkey items need to have same direction - */ - if (pk_index == 1) - sort_info.reverse = reverse; - else if (reverse != sort_info.reverse) - return sort_info; - } - - /* all pathkeys should be processed */ - Assert(lc == NULL); + sort_info.use_compressed_sort = match_pathkeys_to_compression_orderby(pathkeys, + chunk_em_exprs, + i, + compression_info, + &sort_info.reverse); - sort_info.can_pushdown_sort = true; return sort_info; } diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.h b/tsl/src/nodes/decompress_chunk/decompress_chunk.h index d224c2a3394..77f2663e1a3 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.h +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.h @@ -22,6 +22,10 @@ typedef struct CompressionInfo RangeTblEntry *compressed_rte; RangeTblEntry *ht_rte; + FormData_chunk compressed_fd; + Oid compressed_reloid; + Oid compression_hypertable_reloid; + Oid compresseddata_oid; CompressionSettings *settings; @@ -42,15 +46,15 @@ typedef struct CompressionInfo /* compressed chunk attribute numbers for columns that are compressed */ Bitmapset *compressed_attnos_in_compressed_chunk; - bool single_chunk; /* query on explicit chunk */ - bool has_seq_num; /* legacy sequence number support */ - + bool single_chunk; /* query on explicit chunk */ + bool has_seq_num; /* legacy sequence number support */ + Relids parent_relids; /* relids of the parent hypertable and UNION */ } CompressionInfo; typedef struct DecompressChunkPath { CustomPath custom_path; - CompressionInfo *info; + const CompressionInfo *info; List *required_compressed_pathkeys; bool needs_sequence_num; diff --git a/tsl/src/nodes/decompress_chunk/decompress_context.h b/tsl/src/nodes/decompress_chunk/decompress_context.h index bd12927d77e..830f52f2e50 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_context.h +++ b/tsl/src/nodes/decompress_chunk/decompress_context.h @@ -73,7 +73,7 @@ typedef struct DecompressContext List *vectorized_quals_constified; bool reverse; - bool batch_sorted_merge; /* Merge append optimization enabled */ + bool batch_sorted_merge; /* Batch sorted merge optimization enabled. */ bool enable_bulk_decompression; /* diff --git a/tsl/src/nodes/decompress_chunk/exec.c b/tsl/src/nodes/decompress_chunk/exec.c index 18d1ec1e54b..1ffb68bd5a8 100644 --- a/tsl/src/nodes/decompress_chunk/exec.c +++ b/tsl/src/nodes/decompress_chunk/exec.c @@ -212,7 +212,7 @@ decompress_chunk_begin(CustomScanState *node, EState *estate, int eflags) node->ss.ss_ScanTupleSlot->tts_tupleDescriptor); } } - /* Sort keys should only be present when sorted_merge_append is used */ + /* Sort keys should only be present when batch sorted merge is used. */ Assert(dcontext->batch_sorted_merge == true || list_length(chunk_state->sortinfo) == 0); /* diff --git a/tsl/src/nodes/decompress_chunk/planner.c b/tsl/src/nodes/decompress_chunk/planner.c index 785b846e583..e9675282821 100644 --- a/tsl/src/nodes/decompress_chunk/planner.c +++ b/tsl/src/nodes/decompress_chunk/planner.c @@ -252,7 +252,7 @@ static void build_decompression_map(DecompressionMapContext *context, List *compressed_scan_tlist) { DecompressChunkPath *path = context->decompress_path; - CompressionInfo *info = path->info; + const CompressionInfo *info = path->info; /* * Track which normal and metadata columns we were able to find in the * targetlist. @@ -522,7 +522,7 @@ build_decompression_map(DecompressionMapContext *context, List *compressed_scan_ * uncompressed one. Based on replace_nestloop_params */ static Node * -replace_compressed_vars(Node *node, CompressionInfo *info) +replace_compressed_vars(Node *node, const CompressionInfo *info) { if (node == NULL) return NULL; From 7044cd563a5520662c2435222e80b09cc7193dc4 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:52:48 +0100 Subject: [PATCH 2/7] remove unrelated change --- .../nodes/decompress_chunk/decompress_chunk.c | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.c b/tsl/src/nodes/decompress_chunk/decompress_chunk.c index ec47989351c..e67dc637975 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.c +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.c @@ -62,8 +62,10 @@ static void create_compressed_scan_paths(PlannerInfo *root, RelOptInfo *compress const CompressionInfo *compression_info, const SortInfo *sort_info); -static DecompressChunkPath * -decompress_chunk_path_create(PlannerInfo *root, const CompressionInfo *info, Path *compressed_path); +static DecompressChunkPath *decompress_chunk_path_create(PlannerInfo *root, + const CompressionInfo *info, + int parallel_workers, + Path *compressed_path); static void decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, const Chunk *chunk, RelOptInfo *chunk_rel, @@ -893,7 +895,7 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con } Path *chunk_path = - (Path *) decompress_chunk_path_create(root, compression_info, compressed_path); + (Path *) decompress_chunk_path_create(root, compression_info, 0, compressed_path); /* * Create a path for the batch sorted merge optimization. This optimization performs a @@ -1074,7 +1076,10 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, con * If this is a partially compressed chunk we have to combine data * from compressed and uncompressed chunk. */ - path = (Path *) decompress_chunk_path_create(root, compression_info, compressed_path); + path = (Path *) decompress_chunk_path_create(root, + compression_info, + compressed_path->parallel_workers, + compressed_path); if (consider_partial) { @@ -1785,7 +1790,8 @@ decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, const } static DecompressChunkPath * -decompress_chunk_path_create(PlannerInfo *root, const CompressionInfo *info, Path *compressed_path) +decompress_chunk_path_create(PlannerInfo *root, const CompressionInfo *info, int parallel_workers, + Path *compressed_path) { DecompressChunkPath *path; @@ -1824,10 +1830,9 @@ decompress_chunk_path_create(PlannerInfo *root, const CompressionInfo *info, Pat * in a parallel plan we only set parallel_safe to true * when parallel_workers is greater than 0 which is only * the case when creating partial paths. */ + path->custom_path.path.parallel_safe = parallel_workers > 0; + path->custom_path.path.parallel_workers = parallel_workers; path->custom_path.path.parallel_aware = false; - path->custom_path.path.parallel_safe = - info->chunk_rel->consider_parallel && compressed_path->parallel_safe; - path->custom_path.path.parallel_workers = compressed_path->parallel_workers; path->custom_path.custom_paths = list_make1(compressed_path); path->reverse = false; From ab5505fce3ecb94dbf654cbdb1c2be6467ce1dd8 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:32:10 +0100 Subject: [PATCH 3/7] reword the comment --- tsl/src/nodes/decompress_chunk/exec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tsl/src/nodes/decompress_chunk/exec.c b/tsl/src/nodes/decompress_chunk/exec.c index 1ffb68bd5a8..2856a279aa1 100644 --- a/tsl/src/nodes/decompress_chunk/exec.c +++ b/tsl/src/nodes/decompress_chunk/exec.c @@ -212,7 +212,13 @@ decompress_chunk_begin(CustomScanState *node, EState *estate, int eflags) node->ss.ss_ScanTupleSlot->tts_tupleDescriptor); } } - /* Sort keys should only be present when batch sorted merge is used. */ + + /* + * Sort keys should only be present at the level of this node when batch + * sorted merge is used. + * In other cases of sort pushdown, sorting is performed by the underlying + * compressed scan. + */ Assert(dcontext->batch_sorted_merge == true || list_length(chunk_state->sortinfo) == 0); /* From eb9a3debd00cc5bc459d7a0d0ece59c562d39b62 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:53:10 +0100 Subject: [PATCH 4/7] accept the changes --- .../shared/expected/ordered_append-15.out | 574 ++++++++++++------ 1 file changed, 388 insertions(+), 186 deletions(-) diff --git a/tsl/test/shared/expected/ordered_append-15.out b/tsl/test/shared/expected/ordered_append-15.out index e617dc1936a..19f37ac77f4 100644 --- a/tsl/test/shared/expected/ordered_append-15.out +++ b/tsl/test/shared/expected/ordered_append-15.out @@ -2368,18 +2368,26 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -2394,21 +2402,34 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=7196 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(28 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2418,18 +2439,26 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2439,18 +2468,26 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -2465,21 +2502,34 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=7196 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(28 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX @@ -3952,30 +4002,64 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -3990,30 +4074,55 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(49 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -4023,30 +4132,64 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -4056,30 +4199,64 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -4094,30 +4271,55 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(49 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX From a9e4b2cebb6c0446b3f7f59fceacfd695ef604bc Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:54:40 +0100 Subject: [PATCH 5/7] reference REL_17_0-80-gb7467ab71c transparent_decompression-* merge_append_partially_compressed-* ordered_append-* --- .../shared/expected/ordered_append-17.out | 574 ++++++++++++------ 1 file changed, 388 insertions(+), 186 deletions(-) diff --git a/tsl/test/shared/expected/ordered_append-17.out b/tsl/test/shared/expected/ordered_append-17.out index 77f78ff6839..43dab0a2dff 100644 --- a/tsl/test/shared/expected/ordered_append-17.out +++ b/tsl/test/shared/expected/ordered_append-17.out @@ -2311,18 +2311,26 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -2337,21 +2345,34 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=7196 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(28 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2361,18 +2382,26 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2382,18 +2411,26 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -2408,21 +2445,34 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=7196 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(28 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX @@ -3865,30 +3915,64 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -3903,30 +3987,55 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(49 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -3936,30 +4045,64 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -3969,30 +4112,64 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -4007,30 +4184,55 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(49 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX From 64bb23880bfcd89f17083f68dfe0259c794d38ec Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:55:19 +0100 Subject: [PATCH 6/7] reference REL_14_11 ordered_append-* --- .../shared/expected/ordered_append-14.out | 442 ++++++++++++------ 1 file changed, 292 insertions(+), 150 deletions(-) diff --git a/tsl/test/shared/expected/ordered_append-14.out b/tsl/test/shared/expected/ordered_append-14.out index b7fab79f296..de47a266539 100644 --- a/tsl/test/shared/expected/ordered_append-14.out +++ b/tsl/test/shared/expected/ordered_append-14.out @@ -2344,18 +2344,22 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(16 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -2370,21 +2374,31 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(25 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2394,18 +2408,22 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(16 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2415,18 +2433,22 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(16 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -2441,21 +2463,31 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(25 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX @@ -3922,30 +3954,54 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(48 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -3960,30 +4016,49 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(43 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -3993,30 +4068,54 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(48 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -4026,30 +4125,54 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(48 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -4064,30 +4187,49 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(43 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX From 780258e7aa5ef1fb7d39fee31b4303b0da91f7b5 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:55:46 +0100 Subject: [PATCH 7/7] reference REL_16_4-111-g925b3aa857 ordered_append-* --- .../shared/expected/ordered_append-16.out | 574 ++++++++++++------ 1 file changed, 388 insertions(+), 186 deletions(-) diff --git a/tsl/test/shared/expected/ordered_append-16.out b/tsl/test/shared/expected/ordered_append-16.out index e617dc1936a..19f37ac77f4 100644 --- a/tsl/test/shared/expected/ordered_append-16.out +++ b/tsl/test/shared/expected/ordered_append-16.out @@ -2368,18 +2368,26 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -2394,21 +2402,34 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=7196 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(28 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2418,18 +2439,26 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -2439,18 +2468,26 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(12 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_compressed."time") + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(20 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -2465,21 +2502,34 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=8 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=12 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(15 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=7196 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=10076 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(28 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX @@ -3952,30 +4002,64 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY time_bucket, device_id -- must not use ordered append @@ -3990,30 +4074,55 @@ ORDER BY time_bucket('1d', time), LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(49 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -4023,30 +4132,64 @@ ORDER BY date_trunc('day', time) LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY date_trunc :PREFIX @@ -4056,30 +4199,64 @@ ORDER BY 1 LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) - Sort Method: top-N heapsort - -> Result (actual rows=68370 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space_compressed."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=10794 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Result (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) +(58 rows) -- test query with ORDER BY date_trunc, device_id -- must not use ordered append @@ -4094,30 +4271,55 @@ ORDER BY 1, LIMIT 1; QUERY PLAN Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id - Sort Method: top-N heapsort - -> Result (actual rows=27348 loops=1) - -> Append (actual rows=27348 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=4 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Index Scan using compress_hyper_X_X_chunk_device_id__ts_meta_min_1__ts_meta_idx on compress_hyper_X_X_chunk (actual rows=6 loops=1) - Index Cond: (device_id = ANY ('{1,2}'::integer[])) -(24 rows) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=3598 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=5038 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(49 rows) -- test query with now() should result in ordered ChunkAppend :PREFIX