From 80457f791544c6ab12de42046d97e1268aba682a Mon Sep 17 00:00:00 2001 From: Denis Hirn Date: Thu, 21 Mar 2024 13:48:30 +0100 Subject: [PATCH] Add TopN optimization in physical plan mapping Fixes #11260 --- src/execution/physical_plan/plan_limit.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/execution/physical_plan/plan_limit.cpp b/src/execution/physical_plan/plan_limit.cpp index d963179606ba..77fde4b37a74 100644 --- a/src/execution/physical_plan/plan_limit.cpp +++ b/src/execution/physical_plan/plan_limit.cpp @@ -1,9 +1,11 @@ #include "duckdb/execution/operator/helper/physical_limit.hpp" -#include "duckdb/execution/operator/helper/physical_streaming_limit.hpp" #include "duckdb/execution/operator/helper/physical_limit_percent.hpp" +#include "duckdb/execution/operator/helper/physical_streaming_limit.hpp" +#include "duckdb/execution/operator/order/physical_top_n.hpp" #include "duckdb/execution/physical_plan_generator.hpp" #include "duckdb/main/config.hpp" #include "duckdb/planner/operator/logical_limit.hpp" +#include "duckdb/planner/operator/logical_order.hpp" namespace duckdb { @@ -12,6 +14,22 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalLimit &op) auto plan = CreatePlan(*op.children[0]); + if (plan->type == PhysicalOperatorType::ORDER_BY && op.limit_val.Type() == LimitNodeType::CONSTANT_VALUE && + op.offset_val.Type() != LimitNodeType::EXPRESSION_VALUE) { + auto &order_by = plan->Cast(); + // Can not use TopN operator if PhysicalOrder uses projections + if (order_by.projections.empty()) { + idx_t offset_val = 0; + if (op.offset_val.Type() == LimitNodeType::CONSTANT_VALUE) { + offset_val = op.offset_val.GetConstantValue(); + } + auto top_n = make_uniq(op.types, std::move(order_by.orders), op.limit_val.GetConstantValue(), + offset_val, op.estimated_cardinality); + top_n->children.push_back(std::move(order_by.children[0])); + return std::move(top_n); + } + } + unique_ptr limit; switch (op.limit_val.Type()) { case LimitNodeType::EXPRESSION_PERCENTAGE: