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.
This commit is contained in:
Zhiguo Zhou 2024-05-17 23:21:01 +08:00
parent 6e33443926
commit 57ebb726e9

View File

@ -1,5 +1,7 @@
#include <Analyzer/FunctionNode.h>
#include <Columns/ColumnConst.h>
#include <Common/SipHash.h>
#include <Common/FieldVisitorToString.h>
@ -58,12 +60,20 @@ ColumnsWithTypeAndName FunctionNode::getArgumentColumns() const
ColumnWithTypeAndName argument_column;
auto * constant = argument->as<ConstantNode>();
if (isNameOfInFunction(function_name) && i == 1)
{
argument_column.type = std::make_shared<DataTypeSet>();
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<ConstantNode>();
if (constant && !isNotCreatable(argument_column.type))
argument_column.column = argument_column.type->createColumnConst(1, constant->getValue());