HappenLee commented on PR #68498:
URL: https://github.com/apache/doris/pull/68498#issuecomment-5905685902

   必须在这个 PR 内解决,不能以 dismiss / follow-up 方式搁置。
   
   ### 为什么必须在窗口函数下处理
   
   `quantile_union(q) OVER (...)` 
这类窗口聚合会把每一行的中间态都留存到结果列里,`insert_result_into()` 走 `copy_for_result()`:
   
   ```cpp
   QuantileState QuantileState::copy_for_result() const {
       ...
       auto lock = _tdigest_ptr->lock_processed_digest();
       result._tdigest_ptr = std::make_shared<TDigestHolder>(*_tdigest_ptr);   
// 整份拷贝
       ...
   }
   ```
   
   而 `TDigest(const TDigest&) = default` 会连同 vector 的 **capacity** 
一起复制:`_processed` / `_unprocessed` 各自一次预留 `8 * compression + 1` 
个质心。也就是说,每一个留存下来的窗口结果,都会独立持有一份满容量的空 buffer。
   
   - compression = 10000 时,单个结果白占约 `8 * 10000 * sizeof(Centroid)` ≈ 640 KB;
   - 一个 1000 行的窗口,仅这些「预留但没用上」的容量就 ≈ **610 MiB**,且会一直挂到查询结束(`quantile_percent` 
之后只 clear 元素、不还 capacity);
   - 更关键的是 `ColumnQuantileState::allocated_bytes()` 虽然已经接进来,但对这类**被共享/留存**的 
digest 统计口径仍与 join build 预留估算不一致,内存管控可能漏算/低估。
   
   窗口函数不是边角场景——恰恰是「每行产生一个新结果」这条路径,把 `quantile_union` 的中间态以 O(窗口行数) 
的份数复制并长期保留,这是本 PR 引入 COW 之后**最典型的放大路径**。因此这属于需要在本 PR 内修掉的问题,而不是可延后的优化建议。
   
   ### 什么不属于本条
   
   上面这条与前面的 shared_lock 并发问题相互独立:并发问题是**锁粒度/串行**,本条是**留存份数 × 
每份满容量预留**导致的**内存放大**。即便锁已经改成 shared_lock,内存放大依然存在。
   
   ### 建议的最小改法(二选一或组合)
   
   1. `copy_for_result()` 路径上对拷贝出的 digest 做 compact / 释放未用容量:即拷贝时只保留 live 
元素、不保留源 capacity(例如拷贝后 `shrink_to_fit()`,或提供一个成员级拷贝并显式释放 `_unprocessed` 
的预留),确保留存结果不再各留一份满容量 buffer;
   2. 让留存结果的存储与 live 累加器分离,避免为每个窗口结果保留整份写缓冲;
   3. 补一个高 compression + 长窗口的用例(比如 compression=10000、窗口 1w+ 
行)验证峰值内存不随窗口行数线性放大,并把该场景纳入 `allocated_bytes()` 的统计口径。
   
   请在本 PR 内一并处理后重新请求评审。


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to