This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
     new 4d45072760 [Improvement](dict) compute hash only if needed (#18058) 
(#18083)
4d45072760 is described below

commit 4d450727609eba88f6d70679f386590219117063
Author: Gabriel <[email protected]>
AuthorDate: Fri Mar 24 15:49:29 2023 +0800

    [Improvement](dict) compute hash only if needed (#18058) (#18083)
    
    pick #18058
---
 be/src/olap/block_column_predicate.cpp             |  2 +-
 be/src/olap/olap_common.h                          |  3 ++
 be/src/olap/reader.h                               |  2 +-
 be/src/olap/rowset/beta_rowset_reader.h            |  2 +-
 be/src/olap/rowset/segment_v2/segment_iterator.cpp |  8 +--
 be/src/vec/columns/column.h                        |  2 +-
 be/src/vec/columns/column_dictionary.h             | 62 +++++++++++++---------
 be/src/vec/columns/column_nullable.h               |  4 +-
 be/src/vec/exec/scan/new_olap_scan_node.cpp        |  9 +++-
 be/src/vec/exec/scan/new_olap_scan_node.h          |  5 +-
 be/src/vec/exec/scan/new_olap_scanner.cpp          |  7 ++-
 11 files changed, 69 insertions(+), 37 deletions(-)

diff --git a/be/src/olap/block_column_predicate.cpp 
b/be/src/olap/block_column_predicate.cpp
index c35eff0153..0548f88713 100644
--- a/be/src/olap/block_column_predicate.cpp
+++ b/be/src/olap/block_column_predicate.cpp
@@ -81,7 +81,7 @@ void 
SingleColumnBlockPredicate::evaluate_vec(vectorized::MutableColumns& block,
     if (PredicateTypeTraits::is_range(_predicate->type())) {
         column->convert_dict_codes_if_necessary();
     } else if (PredicateTypeTraits::is_bloom_filter(_predicate->type())) {
-        column->generate_hash_values_for_runtime_filter();
+        column->initialize_hash_values_for_runtime_filter();
     }
 
     _predicate->evaluate_vec(*column, size, flags);
diff --git a/be/src/olap/olap_common.h b/be/src/olap/olap_common.h
index 41f9c2132a..5c6647ef60 100644
--- a/be/src/olap/olap_common.h
+++ b/be/src/olap/olap_common.h
@@ -306,6 +306,9 @@ struct OlapReaderStatistics {
     int64_t raw_rows_read = 0;
 
     int64_t rows_vec_cond_filtered = 0;
+    int64_t rows_short_circuit_cond_filtered = 0;
+    int64_t vec_cond_input_rows = 0;
+    int64_t short_circuit_cond_input_rows = 0;
     int64_t rows_vec_del_cond_filtered = 0;
     int64_t vec_cond_ns = 0;
     int64_t short_cond_ns = 0;
diff --git a/be/src/olap/reader.h b/be/src/olap/reader.h
index fbb4a3018d..2ceeb8c5bc 100644
--- a/be/src/olap/reader.h
+++ b/be/src/olap/reader.h
@@ -142,7 +142,7 @@ public:
     uint64_t filtered_rows() const {
         return _stats.rows_del_filtered + _stats.rows_del_by_bitmap +
                _stats.rows_conditions_filtered + 
_stats.rows_vec_del_cond_filtered +
-               _stats.rows_vec_cond_filtered;
+               _stats.rows_vec_cond_filtered + 
_stats.rows_short_circuit_cond_filtered;
     }
 
     void set_batch_size(int batch_size) { _batch_size = batch_size; }
diff --git a/be/src/olap/rowset/beta_rowset_reader.h 
b/be/src/olap/rowset/beta_rowset_reader.h
index d09cf5445f..3ca18b17f9 100644
--- a/be/src/olap/rowset/beta_rowset_reader.h
+++ b/be/src/olap/rowset/beta_rowset_reader.h
@@ -59,7 +59,7 @@ public:
     int64_t filtered_rows() override {
         return _stats->rows_del_filtered + _stats->rows_del_by_bitmap +
                _stats->rows_conditions_filtered + 
_stats->rows_vec_del_cond_filtered +
-               _stats->rows_vec_cond_filtered;
+               _stats->rows_vec_cond_filtered + 
_stats->rows_short_circuit_cond_filtered;
     }
 
     RowsetTypePB type() const override { return RowsetTypePB::BETA_ROWSET; }
diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.cpp 
b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
index ea21e6a50b..d9cac145c8 100644
--- a/be/src/olap/rowset/segment_v2/segment_iterator.cpp
+++ b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
@@ -1090,6 +1090,7 @@ uint16_t 
SegmentIterator::_evaluate_vectorization_predicate(uint16_t* sel_rowid_
         }
     }
 
+    _opts.stats->vec_cond_input_rows += original_size;
     _opts.stats->rows_vec_cond_filtered += original_size - new_size;
     return new_size;
 }
@@ -1107,7 +1108,8 @@ uint16_t 
SegmentIterator::_evaluate_short_circuit_predicate(uint16_t* vec_sel_ro
         auto& short_cir_column = _current_return_columns[column_id];
         selected_size = predicate->evaluate(*short_cir_column, 
vec_sel_rowid_idx, selected_size);
     }
-    _opts.stats->rows_vec_cond_filtered += original_size - selected_size;
+    _opts.stats->short_circuit_cond_input_rows += original_size;
+    _opts.stats->rows_short_circuit_cond_filtered += original_size - 
selected_size;
 
     // evaluate delete condition
     original_size = selected_size;
@@ -1295,7 +1297,7 @@ void 
SegmentIterator::_convert_dict_code_for_predicate_if_necessary() {
     }
 
     for (auto column_id : _delete_bloom_filter_column_ids) {
-        
_current_return_columns[column_id].get()->generate_hash_values_for_runtime_filter();
+        
_current_return_columns[column_id].get()->initialize_hash_values_for_runtime_filter();
     }
 }
 
@@ -1307,7 +1309,7 @@ void 
SegmentIterator::_convert_dict_code_for_predicate_if_necessary_impl(
     if (PredicateTypeTraits::is_range(predicate->type())) {
         col_ptr->convert_dict_codes_if_necessary();
     } else if (PredicateTypeTraits::is_bloom_filter(predicate->type())) {
-        col_ptr->generate_hash_values_for_runtime_filter();
+        col_ptr->initialize_hash_values_for_runtime_filter();
     }
 }
 
diff --git a/be/src/vec/columns/column.h b/be/src/vec/columns/column.h
index 6bd5ac7855..0a2c66183e 100644
--- a/be/src/vec/columns/column.h
+++ b/be/src/vec/columns/column.h
@@ -111,7 +111,7 @@ public:
     virtual void convert_dict_codes_if_necessary() {}
 
     /// If column is ColumnDictionary, and is a bloom filter predicate, 
generate_hash_values
-    virtual void generate_hash_values_for_runtime_filter() {}
+    virtual void initialize_hash_values_for_runtime_filter() {}
 
     /// Creates empty column with the same type.
     virtual MutablePtr clone_empty() const { return clone_resized(0); }
diff --git a/be/src/vec/columns/column_dictionary.h 
b/be/src/vec/columns/column_dictionary.h
index 2812c07103..ca79748ce2 100644
--- a/be/src/vec/columns/column_dictionary.h
+++ b/be/src/vec/columns/column_dictionary.h
@@ -265,11 +265,11 @@ public:
         return _dict.find_code_by_bound(value, greater, eq);
     }
 
-    void generate_hash_values_for_runtime_filter() override {
-        _dict.generate_hash_values_for_runtime_filter(_type);
+    void initialize_hash_values_for_runtime_filter() override {
+        _dict.initialize_hash_values_for_runtime_filter();
     }
 
-    uint32_t get_hash_value(uint32_t idx) const { return 
_dict.get_hash_value(_codes[idx]); }
+    uint32_t get_hash_value(uint32_t idx) const { return 
_dict.get_hash_value(_codes[idx], _type); }
 
     void find_codes(const phmap::flat_hash_set<StringValue>& values,
                     std::vector<vectorized::UInt8>& selected) const {
@@ -345,31 +345,38 @@ public:
         inline const StringValue& get_value(T code) const { return 
(*_dict_data)[code]; }
 
         // The function is only used in the runtime filter feature
-        inline void generate_hash_values_for_runtime_filter(FieldType type) {
+        inline void initialize_hash_values_for_runtime_filter() {
             if (_hash_values.empty()) {
                 _hash_values.resize(_dict_data->size());
-                for (size_t i = 0; i < _dict_data->size(); i++) {
-                    auto& sv = (*_dict_data)[i];
-                    // The char data is stored in the disk with the schema 
length,
-                    // and zeros are filled if the length is insufficient
-
-                    // When reading data, use 
shrink_char_type_column_suffix_zero(_char_type_idx)
-                    // Remove the suffix 0
-                    // When writing data, use the CharField::consume function 
to fill in the trailing 0.
-
-                    // For dictionary data of char type, sv.len is the schema 
length,
-                    // so use strnlen to remove the 0 at the end to get the 
actual length.
-                    int32_t len = sv.len;
-                    if (type == OLAP_FIELD_TYPE_CHAR) {
-                        len = strnlen(sv.ptr, sv.len);
-                    }
-                    uint32_t hash_val = HashUtil::murmur_hash3_32(sv.ptr, len, 
0);
-                    _hash_values[i] = hash_val;
-                }
+                _compute_hash_value_flags.resize(_dict_data->size());
+                _compute_hash_value_flags.assign(_dict_data->size(), 0);
             }
         }
 
-        inline uint32_t get_hash_value(T code) const { return 
_hash_values[code]; }
+        inline uint32_t get_hash_value(T code, FieldType type) const {
+            if (_compute_hash_value_flags[code]) {
+                return _hash_values[code];
+            } else {
+                auto& sv = (*_dict_data)[code];
+                // The char data is stored in the disk with the schema length,
+                // and zeros are filled if the length is insufficient
+
+                // When reading data, use 
shrink_char_type_column_suffix_zero(_char_type_idx)
+                // Remove the suffix 0
+                // When writing data, use the CharField::consume function to 
fill in the trailing 0.
+
+                // For dictionary data of char type, sv.size is the schema 
length,
+                // so use strnlen to remove the 0 at the end to get the actual 
length.
+                int32_t len = sv.len;
+                if (type == OLAP_FIELD_TYPE_CHAR) {
+                    len = strnlen(sv.ptr, sv.len);
+                }
+                uint32_t hash_val = HashUtil::murmur_hash3_32(sv.ptr, len, 0);
+                _hash_values[code] = hash_val;
+                _compute_hash_value_flags[code] = 1;
+                return _hash_values[code];
+            }
+        }
 
         // For > , code takes upper_bound - 1; For >= , code takes upper_bound
         // For < , code takes upper_bound; For <=, code takes upper_bound - 1
@@ -414,9 +421,13 @@ public:
             _dict_data->clear();
             _code_convert_table.clear();
             _hash_values.clear();
+            _compute_hash_value_flags.clear();
         }
 
-        void clear_hash_values() { _hash_values.clear(); }
+        void clear_hash_values() {
+            _hash_values.clear();
+            _compute_hash_value_flags.clear();
+        }
 
         void sort() {
             size_t dict_size = _dict_data->size();
@@ -486,7 +497,8 @@ public:
         // But in TPC-DS 1GB q60,we see no significant improvement.
         // This may because the magnitude of the data is not large enough(in 
q60, only about 80k rows data is filtered for largest table)
         // So we may need more test here.
-        HashValueContainer _hash_values;
+        mutable HashValueContainer _hash_values;
+        mutable std::vector<uint8> _compute_hash_value_flags;
         IColumn::Permutation _perm;
         size_t _total_str_len;
     };
diff --git a/be/src/vec/columns/column_nullable.h 
b/be/src/vec/columns/column_nullable.h
index 2b053ef939..fe34724954 100644
--- a/be/src/vec/columns/column_nullable.h
+++ b/be/src/vec/columns/column_nullable.h
@@ -314,8 +314,8 @@ public:
         get_nested_column().convert_dict_codes_if_necessary();
     }
 
-    void generate_hash_values_for_runtime_filter() override {
-        get_nested_column().generate_hash_values_for_runtime_filter();
+    void initialize_hash_values_for_runtime_filter() override {
+        get_nested_column().initialize_hash_values_for_runtime_filter();
     }
 
     void sort_column(const ColumnSorter* sorter, EqualFlags& flags, 
IColumn::Permutation& perms,
diff --git a/be/src/vec/exec/scan/new_olap_scan_node.cpp 
b/be/src/vec/exec/scan/new_olap_scan_node.cpp
index f0a484d84e..076b9f89ea 100644
--- a/be/src/vec/exec/scan/new_olap_scan_node.cpp
+++ b/be/src/vec/exec/scan/new_olap_scan_node.cpp
@@ -75,7 +75,14 @@ Status NewOlapScanNode::_init_profile() {
     _block_init_seek_counter = ADD_COUNTER(_segment_profile, 
"BlockInitSeekCount", TUnit::UNIT);
     _block_conditions_filtered_timer = ADD_TIMER(_segment_profile, 
"BlockConditionsFilteredTime");
 
-    _rows_vec_cond_counter = ADD_COUNTER(_segment_profile, 
"RowsVectorPredFiltered", TUnit::UNIT);
+    _rows_vec_cond_filtered_counter =
+            ADD_COUNTER(_segment_profile, "RowsVectorPredFiltered", 
TUnit::UNIT);
+    _rows_short_circuit_cond_filtered_counter =
+            ADD_COUNTER(_segment_profile, "RowsShortCircuitPredFiltered", 
TUnit::UNIT);
+    _rows_vec_cond_input_counter =
+            ADD_COUNTER(_segment_profile, "RowsVectorPredInput", TUnit::UNIT);
+    _rows_short_circuit_cond_input_counter =
+            ADD_COUNTER(_segment_profile, "RowsShortCircuitPredInput", 
TUnit::UNIT);
     _vec_cond_timer = ADD_TIMER(_segment_profile, "VectorPredEvalTime");
     _short_cond_timer = ADD_TIMER(_segment_profile, "ShortPredEvalTime");
     _first_read_timer = ADD_TIMER(_segment_profile, "FirstReadTime");
diff --git a/be/src/vec/exec/scan/new_olap_scan_node.h 
b/be/src/vec/exec/scan/new_olap_scan_node.h
index 4305faf0a8..4e2869c945 100644
--- a/be/src/vec/exec/scan/new_olap_scan_node.h
+++ b/be/src/vec/exec/scan/new_olap_scan_node.h
@@ -78,7 +78,10 @@ private:
     RuntimeProfile::Counter* _read_uncompressed_counter = nullptr;
     RuntimeProfile::Counter* _raw_rows_counter = nullptr;
 
-    RuntimeProfile::Counter* _rows_vec_cond_counter = nullptr;
+    RuntimeProfile::Counter* _rows_vec_cond_filtered_counter = nullptr;
+    RuntimeProfile::Counter* _rows_short_circuit_cond_filtered_counter = 
nullptr;
+    RuntimeProfile::Counter* _rows_vec_cond_input_counter = nullptr;
+    RuntimeProfile::Counter* _rows_short_circuit_cond_input_counter = nullptr;
     RuntimeProfile::Counter* _vec_cond_timer = nullptr;
     RuntimeProfile::Counter* _short_cond_timer = nullptr;
     RuntimeProfile::Counter* _output_col_timer = nullptr;
diff --git a/be/src/vec/exec/scan/new_olap_scanner.cpp 
b/be/src/vec/exec/scan/new_olap_scanner.cpp
index 7c78a92b27..08da003a5b 100644
--- a/be/src/vec/exec/scan/new_olap_scanner.cpp
+++ b/be/src/vec/exec/scan/new_olap_scanner.cpp
@@ -394,7 +394,12 @@ void NewOlapScanner::_update_counters_before_close() {
     COUNTER_UPDATE(olap_parent->_lazy_read_seek_timer, 
stats.block_lazy_read_seek_ns);
     COUNTER_UPDATE(olap_parent->_lazy_read_seek_counter, 
stats.block_lazy_read_seek_num);
     COUNTER_UPDATE(olap_parent->_output_col_timer, stats.output_col_ns);
-    COUNTER_UPDATE(olap_parent->_rows_vec_cond_counter, 
stats.rows_vec_cond_filtered);
+    COUNTER_UPDATE(olap_parent->_rows_vec_cond_filtered_counter, 
stats.rows_vec_cond_filtered);
+    COUNTER_UPDATE(olap_parent->_rows_short_circuit_cond_filtered_counter,
+                   stats.rows_short_circuit_cond_filtered);
+    COUNTER_UPDATE(olap_parent->_rows_vec_cond_input_counter, 
stats.vec_cond_input_rows);
+    COUNTER_UPDATE(olap_parent->_rows_short_circuit_cond_input_counter,
+                   stats.short_circuit_cond_input_rows);
 
     COUNTER_UPDATE(olap_parent->_stats_filtered_counter, 
stats.rows_stats_filtered);
     COUNTER_UPDATE(olap_parent->_bf_filtered_counter, stats.rows_bf_filtered);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to