mirror of
https://github.com/apache/doris.git
synced 2026-11-04 07:31:17 +00:00
Count aggregation without GROUP BY reaches
AggFnEvaluator::execute_single_add(), which calls
add_batch_single_place(). AggregateFunctionCount and
AggregateFunctionCountNotNullUnary previously inherited the row-by-row
helper there, so count(*) and count(nullable_expr) paid per-row
add/is_null_at costs even when all rows were aggregated into one state.
This patch adds batch implementations: count(*) increments the state
once by batch_size, while unary count(nullable_expr) checks the nullable
null map once and fast-paths the no-NULL case to count += batch_size.
When NULLs exist it uses simd::count_zero_num() over the null map to
count non-NULL rows. The nullable class name is kept because SQL
count(expr) counts non-NULL values, not NULL values.
Performance:
test with sql
```sql
select count(nullable(number)) from numbers("number"="1000000000");
select count(nullable(if(number >= 0, null, number))) from numbers("number"="1000000000");
select count(nullable(if(number % 2 = 0, number, null))) from numbers("number"="1000000000");
```
get result
```
Scenario before median / mean after median / mean median diff
━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━
non NULL 645 / 648.6 ms 555 / 556.4 ms -14.0%
─────────── ────────────────────── ───────────────────── ─────────────
all NULL 1541 / 1539.6 ms 1448 / 1450.6 ms -6.0%
─────────── ────────────────────── ───────────────────── ─────────────
half NULL 4256 / 4261.2 ms 4192 / 4232.2 ms -1.5%
```
56 lines
2.4 KiB
C++
56 lines
2.4 KiB
C++
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "core/data_type/data_type_nullable.h"
|
|
#include "core/data_type/data_type_number.h"
|
|
#include "exprs/aggregate/agg_function_test.h"
|
|
|
|
namespace doris {
|
|
|
|
struct AggregateFunctionCountTest : public AggregateFunctiontest {};
|
|
|
|
TEST_F(AggregateFunctionCountTest, test_int64) {
|
|
create_agg("count", false, {std::make_shared<DataTypeInt64>()},
|
|
std::make_shared<DataTypeInt64>());
|
|
|
|
execute(Block({ColumnHelper::create_column_with_name<DataTypeInt64>({1, 2, 3})}),
|
|
ColumnHelper::create_column_with_name<DataTypeInt64>({3}));
|
|
}
|
|
|
|
TEST_F(AggregateFunctionCountTest, test_nullable_int64_without_null) {
|
|
create_agg("count", false,
|
|
{std::make_shared<DataTypeNullable>(std::make_shared<DataTypeInt64>())},
|
|
std::make_shared<DataTypeInt64>());
|
|
|
|
execute(Block({ColumnHelper::create_nullable_column_with_name<DataTypeInt64>({1, 2, 3, 4},
|
|
{0, 0, 0, 0})}),
|
|
ColumnHelper::create_column_with_name<DataTypeInt64>({4}));
|
|
}
|
|
|
|
TEST_F(AggregateFunctionCountTest, test_nullable_int64_with_null) {
|
|
create_agg("count", false,
|
|
{std::make_shared<DataTypeNullable>(std::make_shared<DataTypeInt64>())},
|
|
std::make_shared<DataTypeInt64>());
|
|
|
|
execute(Block({ColumnHelper::create_nullable_column_with_name<DataTypeInt64>({1, 2, 3, 4, 5},
|
|
{0, 1, 0, 1, 0})}),
|
|
ColumnHelper::create_column_with_name<DataTypeInt64>({3}));
|
|
}
|
|
} // namespace doris
|