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