From 57ebb726e9fa60b0ade0a66aae1868abdbcbe0b9 Mon Sep 17 00:00:00 2001 From: Zhiguo Zhou Date: Fri, 17 May 2024 23:21:01 +0800 Subject: [PATCH] Analyzer: Optimize resolution of in(LowCardinality, ConstantSet) When the FunctionIn applies to a LowCardinality and a constant set, its return type is expected to be resolved as LowCardinality also so that its argument of LowCardinality column would not be converted to a full one and much computation cost for iterating the rows in DB::Set::executeImplCase could be saved during the execution phase. This condition is fulfilled when FunctionNode::getArgumentColumns returns a LowCardinality column for FunctionIn's 1st argument,and a const column for the other. However, it's actually unfulfilled as a null column is returned for the 2nd argument instead in the Analyzer. This commit revised FunctionNode::getArgumentColumns to return a ColumnConst(ColumnSet) in such cases in order to turn on the opti- mization of LowCardinality. A significant performance gain of 1.39x is observed in query 3.3 of Star Schema Benchmark on the Intel ICX server with 160 vcpus. --- src/Analyzer/FunctionNode.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Analyzer/FunctionNode.cpp b/src/Analyzer/FunctionNode.cpp index f13842cf67c..e98b04fe9a9 100644 --- a/src/Analyzer/FunctionNode.cpp +++ b/src/Analyzer/FunctionNode.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -58,12 +60,20 @@ ColumnsWithTypeAndName FunctionNode::getArgumentColumns() const ColumnWithTypeAndName argument_column; + auto * constant = argument->as(); if (isNameOfInFunction(function_name) && i == 1) + { argument_column.type = std::make_shared(); + if (constant) + { + /// Created but not filled for the analysis during function resolution. + FutureSetPtr empty_set; + argument_column.column = ColumnConst::create(ColumnSet::create(1, empty_set), 1); + } + } else argument_column.type = argument->getResultType(); - auto * constant = argument->as(); if (constant && !isNotCreatable(argument_column.type)) argument_column.column = argument_column.type->createColumnConst(1, constant->getValue());