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

liaoxin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 288fef58c09 [performance](load) do not copy input_block in memtable 
(#36939)
288fef58c09 is described below

commit 288fef58c0944ea967e2d0a2b6d8ac5dcb524302
Author: Kaijie Chen <c...@apache.org>
AuthorDate: Sat Jun 29 16:06:35 2024 +0800

    [performance](load) do not copy input_block in memtable (#36939)
    
    Pass `column_offset` to `Block::clone_without_columns()` and
    `MutableBlock::add_rows()`,
    so we do not need to copy `input_block` in `MemTable::insert()`.
    
    To optimize performance in cases with many (e.g. 12k+) tablets:
    
    Before:
    
    ```
    -  DeltaWriterWriteTime:  1m58s
       -  MemTableWriterFlushTime:  0ns
       -  MemTableWriterLockTime:  1s41ms
       -  MemTableWriterShrinkTime:  0ns
       -  MemTableWriterWriteTime:  1m53s
          -  MemTableCopyCount:  12.044003M  (12044003)
          -  MemTableCopyTime:  42s857ms
          -  MemTableCopyTime0:  11s866ms
          -  MemTableInitTime:  13.384ms
          -  MemTableInsertTime:  51s543ms
    ```
    
    After:
    
    ```
    -  DeltaWriterWriteTime:  1m
       -  MemTableWriterFlushTime:  0ns
       -  MemTableWriterLockTime:  971.481ms
       -  MemTableWriterShrinkTime:  0ns
       -  MemTableWriterWriteTime:  55s274ms
          -  MemTableCopyCount:  0
          -  MemTableCopyTime:  0ns
          -  MemTableCopyTime0:  0ns
          -  MemTableInitTime:  18.746ms
          -  MemTableInsertTime:  53s772ms
    ```
---
 be/src/olap/memtable.cpp  | 14 ++++++--------
 be/src/vec/core/block.cpp | 25 ++++++++++++++++++-------
 be/src/vec/core/block.h   |  5 +++--
 3 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/be/src/olap/memtable.cpp b/be/src/olap/memtable.cpp
index 750026c289d..e55fd678bd2 100644
--- a/be/src/olap/memtable.cpp
+++ b/be/src/olap/memtable.cpp
@@ -180,16 +180,14 @@ int RowInBlockComparator::operator()(const RowInBlock* 
left, const RowInBlock* r
 
 Status MemTable::insert(const vectorized::Block* input_block,
                         const std::vector<uint32_t>& row_idxs) {
-    vectorized::Block target_block = *input_block;
-    target_block = input_block->copy_block(_column_offset);
     if (_is_first_insertion) {
         _is_first_insertion = false;
-        auto cloneBlock = target_block.clone_without_columns();
+        auto cloneBlock = input_block->clone_without_columns(&_column_offset);
         _input_mutable_block = 
vectorized::MutableBlock::build_mutable_block(&cloneBlock);
         _vec_row_comparator->set_block(&_input_mutable_block);
         _output_mutable_block = 
vectorized::MutableBlock::build_mutable_block(&cloneBlock);
         if (_keys_type != KeysType::DUP_KEYS) {
-            _init_agg_functions(&target_block);
+            _init_agg_functions(input_block);
         }
         if (_tablet_schema->has_sequence_col()) {
             if (_is_partial_update) {
@@ -210,11 +208,11 @@ Status MemTable::insert(const vectorized::Block* 
input_block,
     auto num_rows = row_idxs.size();
     size_t cursor_in_mutableblock = _input_mutable_block.rows();
     auto block_size0 = _input_mutable_block.allocated_bytes();
-    RETURN_IF_ERROR(_input_mutable_block.add_rows(&target_block, 
row_idxs.data(),
-                                                  row_idxs.data() + num_rows));
+    RETURN_IF_ERROR(_input_mutable_block.add_rows(input_block, row_idxs.data(),
+                                                  row_idxs.data() + num_rows, 
&_column_offset));
     auto block_size1 = _input_mutable_block.allocated_bytes();
     g_memtable_input_block_allocated_size << block_size1 - block_size0;
-    auto input_size = size_t(target_block.bytes() * num_rows / 
target_block.rows() *
+    auto input_size = size_t(input_block->bytes() * num_rows / 
input_block->rows() *
                              config::memtable_insert_memory_ratio);
     _mem_usage += input_size;
     _insert_mem_tracker->consume(input_size);
@@ -348,7 +346,7 @@ Status MemTable::_sort_by_cluster_keys() {
         row_pos_vec.emplace_back(row_in_blocks[i]->_row_pos);
     }
     return _output_mutable_block.add_rows(&in_block, row_pos_vec.data(),
-                                          row_pos_vec.data() + 
in_block.rows());
+                                          row_pos_vec.data() + 
in_block.rows(), &_column_offset);
 }
 
 void MemTable::_sort_one_column(std::vector<RowInBlock*>& row_in_blocks, Tie& 
tie,
diff --git a/be/src/vec/core/block.cpp b/be/src/vec/core/block.cpp
index 676674e8ec0..22062dc5310 100644
--- a/be/src/vec/core/block.cpp
+++ b/be/src/vec/core/block.cpp
@@ -653,12 +653,19 @@ Block Block::clone_with_columns(const Columns& columns) 
const {
     return res;
 }
 
-Block Block::clone_without_columns() const {
+Block Block::clone_without_columns(const std::vector<int>* column_offset) 
const {
     Block res;
 
-    size_t num_columns = data.size();
-    for (size_t i = 0; i < num_columns; ++i) {
-        res.insert({nullptr, data[i].type, data[i].name});
+    if (column_offset != nullptr) {
+        size_t num_columns = column_offset->size();
+        for (size_t i = 0; i < num_columns; ++i) {
+            res.insert({nullptr, data[(*column_offset)[i]].type, 
data[(*column_offset)[i]].name});
+        }
+    } else {
+        size_t num_columns = data.size();
+        for (size_t i = 0; i < num_columns; ++i) {
+            res.insert({nullptr, data[i].type, data[i].name});
+        }
     }
     return res;
 }
@@ -1008,14 +1015,18 @@ void MutableBlock::add_row(const Block* block, int row) 
{
 }
 
 Status MutableBlock::add_rows(const Block* block, const uint32_t* row_begin,
-                              const uint32_t* row_end) {
+                              const uint32_t* row_end, const std::vector<int>* 
column_offset) {
     RETURN_IF_CATCH_EXCEPTION({
         DCHECK_LE(columns(), block->columns());
+        if (column_offset != nullptr) {
+            DCHECK_EQ(columns(), column_offset->size());
+        }
         const auto& block_data = block->get_columns_with_type_and_name();
         for (size_t i = 0; i < _columns.size(); ++i) {
-            DCHECK_EQ(_data_types[i]->get_name(), 
block_data[i].type->get_name());
+            const auto& src_col = column_offset ? 
block_data[(*column_offset)[i]] : block_data[i];
+            DCHECK_EQ(_data_types[i]->get_name(), src_col.type->get_name());
             auto& dst = _columns[i];
-            const auto& src = *block_data[i].column.get();
+            const auto& src = *src_col.column.get();
             DCHECK_GE(src.size(), row_end - row_begin);
             dst->insert_indices_from(src, row_begin, row_end);
         }
diff --git a/be/src/vec/core/block.h b/be/src/vec/core/block.h
index 3611252ea59..6f50ff0035a 100644
--- a/be/src/vec/core/block.h
+++ b/be/src/vec/core/block.h
@@ -223,7 +223,7 @@ public:
 
     void set_columns(const Columns& columns);
     Block clone_with_columns(const Columns& columns) const;
-    Block clone_without_columns() const;
+    Block clone_without_columns(const std::vector<int>* column_offset = 
nullptr) const;
 
     /** Get empty columns with the same types as in block. */
     MutableColumns clone_empty_columns() const;
@@ -607,7 +607,8 @@ public:
 
     void add_row(const Block* block, int row);
     // Batch add row should return error status if allocate memory failed.
-    Status add_rows(const Block* block, const uint32_t* row_begin, const 
uint32_t* row_end);
+    Status add_rows(const Block* block, const uint32_t* row_begin, const 
uint32_t* row_end,
+                    const std::vector<int>* column_offset = nullptr);
     Status add_rows(const Block* block, size_t row_begin, size_t length);
     Status add_rows(const Block* block, std::vector<int64_t> rows);
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to