Skip to content

branch-4.0: [Opt](func) Improve AggFunc Percentile performance (#62520) - #65961

Draft
linrrzqqq wants to merge 2 commits into
apache:branch-4.0from
linrrzqqq:pick-62520-branch-4.0
Draft

branch-4.0: [Opt](func) Improve AggFunc Percentile performance (#62520)#65961
linrrzqqq wants to merge 2 commits into
apache:branch-4.0from
linrrzqqq:pick-62520-branch-4.0

Conversation

@linrrzqqq

Copy link
Copy Markdown
Collaborator

Summary

Validation

  • ./build.sh --be -j 90 (ASAN): passed
  • ./build.sh --fe -j 1: passed; Checkstyle 0 violations
  • ASAN targeted BE tests: 15/15 passed
    • AggTest.percentile_query_option_routes_default_names_to_v2
    • AggTest.percentile_v2_skips_nan
    • PercentileUtilTest.*

@linrrzqqq
linrrzqqq requested a review from morningman as a code owner July 23, 2026 10:16
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@linrrzqqq

linrrzqqq commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

breakwater migration test

@linrrzqqq
linrrzqqq marked this pull request as draft July 23, 2026 13:07
- Reworked exact percentile state into a simpler `values +
PercentileLevels + inited_flag` layout.
- Removed the old Counts-based exact percentile path and replaced it
with a lightweight `PercentileLevels` metadata structure.
- Reduced add-path overhead by directly appending values into a
contiguous buffer and initializing `percentile levels` only once.
- Optimized multi-quantile finalize(`percentile_array`) by sorting
quantiles through permutation once, then reusing incremental
`nth_element` selection.

before:
```text
Doris> select percentile(FUniqID, 0.91) from hits_100m;
+---------------------------+
| percentile(FUniqID, 0.91) |
+---------------------------+
|     8.749975206154981e+18 |
+---------------------------+
1 row in set (6.149 sec)

Doris> select percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56]) from hits_100m;
+------------------------------------------------------------------------------------------------+
| percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56])                                      |
+------------------------------------------------------------------------------------------------+
| [0, 5.097819197233503e+18, 5.68906185719365e+18, 6.281280528073601e+18, 6.869583632113269e+18] |
+------------------------------------------------------------------------------------------------+
1 row in set (28.984 sec)

Doris> select percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 0.91]) from hits_100m;
ERROR 1105 (HY000): errCode = 2, detailMessage = (127.0.0.1)[E-3113]string column length is too large: total_length=7200000149, element_number=0, rows=0
```

now
```text
Doris> select percentile(FUniqID, 0.91) from hits_100m;
+---------------------------+
| percentile(FUniqID, 0.91) |
+---------------------------+
|     8.749975206154981e+18 |
+---------------------------+
1 row in set (2.107 sec)

Doris> select percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56]) from hits_100m;
+------------------------------------------------------------------------------------------------+
| percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56])                                      |
+------------------------------------------------------------------------------------------------+
| [0, 5.097819197233503e+18, 5.68906185719365e+18, 6.281280528073601e+18, 6.869583632113269e+18] |
+------------------------------------------------------------------------------------------------+
1 row in set (5.903 sec)

Doris> select percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 0.91]) from hits_100m;
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| percentile_array(FUniqID, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 0.91])                                                                                                          |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| [0, 5.097819197233503e+18, 5.68906185719365e+18, 6.281280528073601e+18, 6.869583632113269e+18, 7.459044216605808e+18, 8.044902013692362e+18, 8.640523572825436e+18, 8.749975206154981e+18] |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (8.866 sec)
```
Backport the follow-up correctness fix from apache#63472 so percentile v2 ignores NaN inputs and returns NaN for all-NaN input. Add direct scalar and array unit coverage.
@linrrzqqq
linrrzqqq force-pushed the pick-62520-branch-4.0 branch from 0023dec to 55abea4 Compare July 23, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants