enhance: optimize term expr performance (#45671)

issue: https://github.com/milvus-io/milvus/issues/45641
pr: https://github.com/milvus-io/milvus/pull/45491

Signed-off-by: sunby <sunbingyi1992@gmail.com>
This commit is contained in:
Bingyi Sun 2025-11-19 19:43:06 +08:00 committed by GitHub
parent 08ae6b5fcc
commit e4a85ab92e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 17 deletions

View File

@ -216,7 +216,7 @@ class FlatVectorElement : public MultiElement {
In(const ValueType& value) const override {
if (std::holds_alternative<T>(value)) {
for (const auto& v : values_) {
if (v == value)
if (v == std::get<T>(value))
return true;
}
}

View File

@ -982,7 +982,7 @@ class SegmentExpr : public Expr {
template <typename T, typename FUNC, typename... ValTypes>
VectorPtr
ProcessIndexChunks(FUNC func, ValTypes... values) {
ProcessIndexChunks(FUNC func, const ValTypes&... values) {
typedef std::
conditional_t<std::is_same_v<T, std::string_view>, std::string, T>
IndexInnerType;

View File

@ -837,29 +837,36 @@ PhyTermFilterExpr::ExecVisitorImplForIndex() {
return nullptr;
}
std::vector<IndexInnerType> vals;
for (auto& val : expr_->vals_) {
if constexpr (std::is_same_v<T, double>) {
if (val.has_int64_val()) {
// only json field will cast int to double because other fields are casted in proxy
vals.emplace_back(static_cast<double>(val.int64_val()));
continue;
if (!arg_inited_) {
std::vector<IndexInnerType> vals;
for (auto& val : expr_->vals_) {
if constexpr (std::is_same_v<T, double>) {
if (val.has_int64_val()) {
// only json field will cast int to double because other fields are casted in proxy
vals.emplace_back(static_cast<double>(val.int64_val()));
continue;
}
}
// Generic overflow handling for all types
bool overflowed = false;
auto converted_val =
GetValueFromProtoWithOverflow<T>(val, overflowed);
if (!overflowed) {
vals.emplace_back(converted_val);
}
}
// Generic overflow handling for all types
bool overflowed = false;
auto converted_val = GetValueFromProtoWithOverflow<T>(val, overflowed);
if (!overflowed) {
vals.emplace_back(converted_val);
}
arg_set_ = std::make_shared<FlatVectorElement<IndexInnerType>>(vals);
arg_inited_ = true;
}
auto execute_sub_batch = [](Index* index_ptr,
const std::vector<IndexInnerType>& vals) {
TermIndexFunc<T> func;
return func(index_ptr, vals.size(), vals.data());
};
auto res = ProcessIndexChunks<T>(execute_sub_batch, vals);
auto args =
std::dynamic_pointer_cast<FlatVectorElement<IndexInnerType>>(arg_set_);
auto res = ProcessIndexChunks<T>(execute_sub_batch, args->values_);
AssertInfo(res->size() == real_batch_size,
"internal error: expr processed rows {} not equal "
"expect batch size {}",