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

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new c64618c8131 branch-4.1: [Exec](shuffle) random shuffle firstly use 
local channel to improve performance #59431 (#66103)
c64618c8131 is described below

commit c64618c81317d41dabf930846f393ddf06e1ca2b
Author: HappenLee <[email protected]>
AuthorDate: Wed Jul 29 13:53:56 2026 +0800

    branch-4.1: [Exec](shuffle) random shuffle firstly use local channel to 
improve performance #59431 (#66103)
    
    ### What problem does this PR solve?
    
    Issue Number: close #xxx
    
    Related PR: #59431
    
    Problem Summary: Cherry-pick #59431 to branch-4.1. For RANDOM shuffle,
    the exchange sink used to send blocks to channels in round-robin order
    one by one. This change collects local channel ids during init and
    prefers sending to local channels first, reducing network overhead and
    improving performance.
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test: No need to test (pure cherry-pick from master with minor
    conflict resolution on namespace)
    - Behavior changed: No
    - Does this need documentation: No
---
 be/src/exec/operator/exchange_sink_operator.cpp | 12 ++++++++++++
 be/src/exec/operator/exchange_sink_operator.h   |  1 +
 2 files changed, 13 insertions(+)

diff --git a/be/src/exec/operator/exchange_sink_operator.cpp 
b/be/src/exec/operator/exchange_sink_operator.cpp
index 6a64dc212a5..4d767611e1c 100644
--- a/be/src/exec/operator/exchange_sink_operator.cpp
+++ b/be/src/exec/operator/exchange_sink_operator.cpp
@@ -109,6 +109,7 @@ Status ExchangeSinkLocalState::init(RuntimeState* state, 
LocalSinkStateInfo& inf
     size_t local_size = 0;
     for (int i = 0; i < channels.size(); ++i) {
         if (channels[i]->is_local()) {
+            local_channel_ids.push_back(i);
             local_size++;
             _last_local_channel_idx = i;
         }
@@ -509,6 +510,17 @@ Status ExchangeSinkOperatorX::sink_impl(RuntimeState* 
state, Block* block, bool
             }
         }
     } else if (_part_type == TPartitionType::RANDOM) {
+        if (!local_state.local_channel_ids.empty()) {
+            const auto& ids = local_state.local_channel_ids;
+            // Find the first channel ID >= current_channel_idx
+            auto it = std::lower_bound(ids.begin(), ids.end(), 
local_state.current_channel_idx);
+            if (it != ids.end()) {
+                local_state.current_channel_idx = *it;
+            } else {
+                // All IDs are < current_channel_idx; wrap around to the first 
one
+                local_state.current_channel_idx = ids[0];
+            }
+        }
         RETURN_IF_ERROR(send_to_current_channel());
         local_state.current_channel_idx =
                 (local_state.current_channel_idx + 1) % 
local_state.channels.size();
diff --git a/be/src/exec/operator/exchange_sink_operator.h 
b/be/src/exec/operator/exchange_sink_operator.h
index c850c13cac4..09f4cf8b047 100644
--- a/be/src/exec/operator/exchange_sink_operator.h
+++ b/be/src/exec/operator/exchange_sink_operator.h
@@ -103,6 +103,7 @@ public:
         return _distribute_rows_into_channels_timer;
     }
     std::vector<std::shared_ptr<Channel>> channels;
+    std::vector<int> local_channel_ids;
     int current_channel_idx {0}; // index of current channel to send to if 
_random == true
     bool _only_local_exchange {false};
 


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

Reply via email to