SortMergeJoinExec double counts join key columns in the buffered batch reservation

Đang mở
#27,322 3 bình luận 0 reaction 1 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@Kristofferjoha đang làm issue này rồi.

Từ ngày 11/11/2026.

  • #27346 của @Kristofferjoha — đang mở

Đánh giá

Issue này chưa được đánh giá.

Mô tả

bug
Describe the bug

SortMergeJoinExec charges a buffered batch twice for each join key that is a plain column. BufferedBatch::try_new adds batch.get_array_memory_size() and the size of each evaluated join key array. When the key is a column reference, the key array shares its buffers with the batch. The reservation then counts that column two times.

Code: https://github.com/apache/datafusion/blob/34eb6dc5b/datafusion/physical-plan/src/joins/sort_merge_join/materializing_stream.rs#L289-L299

The effect is that a join on a wide string key reserves about twice the memory it holds. This makes the join spill or fail under a memory limit earlier than it should.

To Reproduce

Run this in datafusion-cli (commit 34eb6dc5b on main). Both queries buffer the same data. Only the join key differs.

SET datafusion.execution.target_partitions = 2;
SET datafusion.optimizer.prefer_hash_join = false;
CREATE TABLE l AS SELECT value AS id, repeat('x', 1000) || value AS s FROM generate_series(1, 20000);
CREATE TABLE r AS SELECT value AS id, repeat('x', 1000) || value AS s FROM generate_series(1, 20000);

-- join on the wide string column
EXPLAIN ANALYZE SELECT max(l.id), max(r.id), max(l.s), max(r.s) FROM l JOIN r ON l.s = r.s;
-- join on the integer column, same columns kept
EXPLAIN ANALYZE SELECT max(l.id), max(r.id), max(l.s), max(r.s) FROM l JOIN r ON l.id = r.id;

Observed SortMergeJoinExec metrics:

join key peak_mem_used
l.s = r.s 38.8 MB
l.id = r.id 19.7 MB
Expected behavior

Both queries should report about the same peak_mem_used, because the buffered batches are the same. A key array that is a column of the batch should not be charged again.

Additional context

A possible fix is to charge only the key arrays that do not share buffers with the batch (for example, skip Column keys, or count buffers by pointer once per batch).

Related: https://github.com/apache/datafusion/issues/16841 and https://github.com/apache/datafusion/issues/22758.

Ngôn ngữ chính
Rust
Star
9.6k
Fork
2.6k
Merge trung bình
3 ngày 4 giờ
Pull request đã merge (30 ngày)
345

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của apache/datafusion

Tất cả issue của apache/datafusion

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.