njnu-seafish opened a new issue, #18714:
URL: https://github.com/apache/dolphinscheduler/issues/18714

   ### Search before asking
   
   - [x] I had searched in the 
[issues](https://github.com/apache/dolphinscheduler/issues?q=is%3Aissue) and 
found no similar feature requirement.
   
   
   ### Description
   
   ### Issue
   
   In `org.apache.dolphinscheduler.plugin.task.sql.SqlTask` (module 
`dolphinscheduler-task-sql`), the query result is processed by `resultProcess`: 
every row is first buffered into an `ArrayNode` (`resultJSONArray`), then the 
configured `displayRows` are logged, and the array is reused as the task result 
value and (optionally) as the "query result" alert content. I found two 
inefficiencies worth improving:
   
   #### 1. `displayRows` are logged only after the whole result set is buffered
   
   `resultProcess` first reads every row into `resultJSONArray` and only 
afterwards logs the `displayRows` in a second loop (`log.info("display sql 
result {} rows as follows:", displayRows)` then per-row `log.info("row {} : 
{}", ...)`). For a long-running query with a large result set, no row output 
appears in the worker log until the entire result has been fetched, and the 
array is traversed a second time just for logging.
   
   Note: the full `resultJSONArray` must still be retained because it is the 
task return value and the alert payload when "send alert" is enabled, so the 
goal here is not to reduce peak memory but to (a) log the display rows inline 
as each row is read so the output is streaming/incremental, and (b) drop the 
second traversal over the already-built array.
   
   
   #### 2. `limitAlertContent` re-serializes the whole content on every loop 
iteration
   
   `limitAlertContent(ArrayNode)` builds the size-limited alert content with a 
`while (true)` loop. Each iteration calls `JSONUtils.toJsonString(limited)` and 
then `content.getBytes(StandardCharsets.UTF_8).length` to check the byte 
budget; if the budget is exceeded, the last row is dropped and the loop 
repeats. This means:
   
   - the entire kept sub-array is serialized from scratch on every iteration, 
and
   - the whole string is re-encoded into a fresh `byte[]` on every iteration 
just to measure its length.
   
   When the byte budget is tight and rows are wide or contain multi-byte 
characters, the total cost grows to O(iterations × rows) with repeated full 
serialization and byte-encoding, even though the serialized form of each row 
never changes.
   
   Suggested improvement: serialize each candidate row once (or precompute its 
UTF-8 byte length), keep a running byte count, and assemble the final JSON only 
after deciding how many rows fit; avoid materializing a whole `byte[]` per 
measurement. The output must remain a valid JSON array and still respect the 
configured byte budget (behavior unchanged).
   
   
   
   ### Are you willing to submit a PR?
   
   - [x] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   


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

Reply via email to