hailcpy opened a new pull request, #69059:
URL: https://github.com/apache/doris/pull/69059

   ### What problem does this PR solve?
   
   Issue Number: None
   
   Related PR: None
   
   Problem Summary:
   
   `json_search()` takes quadratic time on JSON arrays. A real 2 MB document 
with 17 arrays of 18,272 strings each takes 18.5 s to search a single row.
   
   Reproduce on 4.1.4.1. Objects of the same size stay flat:
   
   ```sql
   select json_search(
     cast(concat('["', group_concat(cast(number as string), '","'), '"]') as 
json),
     'one', '%zzq%')
   from numbers('number'='40000');
   ```
   
   | array elements | time |
   |---:|---:|
   | 5,000 | 0.13 s |
   | 10,000 | 0.35 s |
   | 20,000 | 1.33 s |
   | 40,000 | 5.24 s |
   | object, 40,000 members | 0.02 s |
   
   Root cause: `FunctionJsonSearch::find_matches` walks arrays by index:
   
   ```cpp
   for (int i = 0; i < array->numElem(); ++i) {
       ...
       const auto* child_element = array->get(i);
   ```
   
   JSONB arrays are packed with variable-length values and no offset table, so 
`ArrayVal::numElem()` and `ArrayVal::get(idx)` each scan the payload from the 
start. Both run on every iteration, which makes each array O(n²). Objects 
already use `ObjectVal`'s forward iterator and stay linear.
   
   Fix: iterate arrays with `ArrayVal::begin()/end()`, the forward iterator the 
JSONB format already provides, and keep a running index for the `$[i]` path 
leg. The same index loop appears in two other places, and this PR fixes them 
too:
   
   - `write_json_value` in `function_jsonb.cpp` (`json_insert` / `json_replace` 
/ `json_set`)
   - `jsonb_detail::array_contains_value` / `array_contains_array` in 
`jsonb_document.h` (`json_contains`). These already hoist `numElem()`, but 
`get(i)` is still O(i).
   
   Elements are visited in the same order and get the same indices, so results 
do not change. The loops stop at `it < end()` rather than `it != end()`, so a 
malformed element length cannot walk past the array payload. This keeps the 
`pch < fence` bound that `numElem()`/`get()` used.
   
   ### Release note
   
   Improve performance of `json_search`, `json_contains`, `json_insert`, 
`json_replace` and `json_set` on large JSON arrays; array traversal is now 
linear instead of quadratic.
   
   ### Check List (For Author)
   
   - Test <!-- At least one of them must be included. -->
       - [ ] Regression test
       - [ ] Unit Test
       - [ ] Manual test (add detailed scripts or steps below)
       - [x] No need to test or manual test. Explain why:
           - [ ] This is a refactor/code format and no logic has been changed.
           - [x] Previous test can cover this change.
           - [ ] No code files have been changed.
           - [ ] Other reason <!-- Add your reason?  -->
   
       Array paths and results are already covered by 
`query_p0/sql_functions/json_functions/json_search.groovy` (nested arrays such 
as `$[1][0].B`), `test_json_function.groovy`, 
`test_json_contains_numeric_equality.groovy` and the `json_contains` cases in 
`be/test/exprs/function/function_jsonb_test.cpp`. I did not build this patch 
locally; I'd appreciate a `run buildall`. The timings above come from an 
unpatched 4.1.4.1 cluster.
   
   - Behavior changed:
       - [x] No.
       - [ ] Yes. <!-- Explain the behavior change -->
   
   - Does this need documentation?
       - [x] No.
       - [ ] Yes. <!-- Add document PR link here. eg: 
https://github.com/apache/doris-website/pull/1214 -->
   
   ### Check List (For Reviewer who merge this PR)
   
   - [ ] Confirm the release note
   - [ ] Confirm test cases
   - [ ] Confirm document
   - [ ] Add branch pick label <!-- Add branch pick label that this PR should 
merge into -->
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
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