Doris-Breakwater commented on issue #68895:
URL: https://github.com/apache/doris/issues/68895#issuecomment-6098962376

   Source review confirms that sampled collection performs a separate, 
**table-wide MIN/MAX query per selected column/index task**. This merits 
statistics-collection scalability investigation. However, an unsampled SQL 
statement does not by itself establish a full scan of column data: eligible 
Doris MIN/MAX queries already use segment zone maps. The reported S3 throttling 
and ingestion impact still need execution evidence.
   
   Verified against the public `4.1.4` tag (commit 
`ad35a140c7fd0b842f18c23300bac581f7d04326`) and master commit 
`dd456ab7a894f54c6553415223c6d5c9c7d4e035`:
   
   1. **Sampling does not constrain the preliminary MIN/MAX query.** 
`doSample()` calls `collectMinMax()` before choosing sample tablets. 
`BASIC_STATS_TEMPLATE` contains neither a tablet/sample restriction nor a 
limit; only the subsequent statistics query receives `TABLET(...)` and, where 
applicable, `LIMIT`. The preliminary bounds are injected into that subsequent 
query. An exception from MIN/MAX is rethrown, preventing the subsequent sample 
query for that task. This applies to columns/indexes selected for collection, 
rather than necessarily every table column in every scheduler cycle. See [4.1.4 
OlapAnalysisTask](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/OlapAnalysisTask.java#L64-L158)
 and [sample parameter 
construction](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/OlapAnalysisTask.java#L303-L348).
   
   2. **Zone-map collection already exists, with eligibility/fallback 
conditions.** The internal statistics context enables MIN/MAX pushdown for 
unique tables and string columns. Nereids can produce a storage-layer MIN/MAX 
aggregate; in 4.1.4, BE uses `VStatisticsIterator` when pushdown is enabled and 
there are no delete-condition predicates. That iterator obtains two bound 
values per segment through `next_batch_of_zone_map()`, instead of reading all 
column values. Otherwise, BE can use `SegmentIterator`. See [internal 
context](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java#L214-L251),
 [planner 
rules](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/AggregateStrategies.java#L150-L239),
 [iterator 
selection](https://github.com/apache/doris/blob/4.1.4/be/src/storage/segment/segment.cpp#L433-L444),
 and [zone-map iterator](https://github.com/apache/dor
 is/blob/4.1.4/be/src/storage/iterator/vgeneric_iterators.cpp#L43-L95). Even 
the metadata path traverses the table's segments and can incur remote metadata 
reads on misses; the actual request volume depends on segment count and cache 
residency.
   
      Master retains the separate unsampled query, but its internal context now 
sets `forcePushDownZonemapMinMax=true`, with corresponding BE handling for 
truncated bounds and delete predicates. Thus the SQL shape is the same, while 
fallback behavior is not identical. See [master 
context](https://github.com/apache/doris/blob/dd456ab7a894f54c6553415223c6d5c9c7d4e035/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java#L189-L227)
 and [master BE 
handling](https://github.com/apache/doris/blob/dd456ab7a894f54c6553415223c6d5c9c7d4e035/be/src/storage/segment/segment.cpp#L527-L540).
 This does not remove table-wide traversal.
   
   3. **Cache and timeout settings require the internal-query context.** The 
statistics context disables page cache and sets cloud `disableFileCache=true`. 
BE maps that flag to disposable I/O/cache classification; already downloaded 
file-cache blocks can still be reused. It is not sufficient evidence of 
complete cache bypass. See [BE 
propagation](https://github.com/apache/doris/blob/4.1.4/be/src/storage/rowset/beta_rowset_reader.cpp#L216-L228),
 [cache 
classification](https://github.com/apache/doris/blob/4.1.4/be/src/io/cache/file_cache_common.h#L165-L176),
 and [cached-block 
handling](https://github.com/apache/doris/blob/4.1.4/be/src/io/cache/cached_remote_file_reader.cpp#L806-L837).
 Query timeout is explicitly taken from global `analyze_timeout`; the 4.1.4 
source default is 43,200 seconds. A 300-second failure therefore needs the 
effective setting and exact error to identify the timeout source. See [timeout 
setting](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/
 org/apache/doris/qe/SessionVariable.java#L1177-L1180).
   
   4. **#68896 can amplify this cost.** Failed terminal jobs skip 
`updateTableStats()`, whereas successful jobs update column statistics metadata 
and `lastAnalyzeTime`. This supports repeated collection eligibility after 
failure, but does not establish the observed cadence. Also, in the inspected 
4.1.4 production Java source, `getHugeTableAutoAnalyzeIntervalInMillis()` has 
no callers; the active collector filters use column eligibility/change checks. 
The deployed scheduling behavior should be verified rather than relying on that 
variable as a cooldown. See [terminal job 
handling](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java#L530-L560)
 and [collector 
eligibility](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsAutoCollector.java#L150-L170).
   
   To establish the expensive execution path and its effect, please provide:
   
   - Exact FE/BE build revisions, anonymized `SHOW CREATE TABLE` (key model, 
merge-on-write setting, column types, partitions and indexes), and 
tablet/rowset/segment counts.
   - One affected MIN/MAX query ID, complete SQL, audit entry, full 
timeout/error message, and matching FE/BE log excerpts. Include effective 
global `analyze_timeout`, sample settings, collection window, and analyze-task 
concurrency.
   - The actual internal-query plan and full profile, including pushed 
aggregation, rows/data pages read, segment counts, remote/local read bytes and 
requests, and segment-metadata load time. A manual `EXPLAIN` must reproduce the 
internal pushdown settings; ordinary session defaults differ. 
`enable_profile_when_analyze` is the existing FE switch for collecting analyze 
profiles.
   - A timestamp-aligned sample of S3 503/curl errors, request-rate metrics and 
load latency, plus analyze job/task history across retries. Please redact 
credentials and sensitive object paths. A controlled off-peak comparison with 
collection paused for this table would help establish attribution.
   
   For immediate containment, the existing collection window can move future 
work off peak. Alternatively, temporarily exclude only this table with `ALTER 
TABLE db.tbl SET ("auto_analyze_policy" = "disable")`, restoring its previous 
policy afterward; this trades statistics freshness for reduced background work 
and does not cancel already running tasks. These gates are checked by 
[canCollect()/column 
eligibility](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java#L1254-L1305)
 and [the table 
policy](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java#L3827-L3839).
 Reducing sample rows leaves the preliminary MIN/MAX query unchanged.
   
   For maintainers, first distinguish missing pushdown/full data reads from 
expensive table-wide metadata traversal. If the latter dominates, evaluate 
batching bounds across columns or reusing metadata with correct version 
visibility, and an explicit option to omit table-wide bounds in sampled 
collection. Unknown bounds have an existing representation: [ColumnStatistic 
deserialization](https://github.com/apache/doris/blob/4.1.4/fe/fe-core/src/main/java/org/apache/doris/statistics/ColumnStatistic.java#L169-L202)
 maps absent bounds to infinities. Sample extrema should not silently become 
authoritative table-wide bounds, since rare extreme values can be missed and 
distort selectivity estimates. Any change needs coverage for outliers, nulls, 
long strings, deletes, key models/indexes and optimizer estimates. Handle retry 
backoff separately in #68896, preserving the distinction between a failed 
attempt and successfully refreshed statistics.
   
   This is source-level triage; no runtime reproduction or supplied profile was 
available, and no code was changed.
   
   Breakwater-GitHub-Analysis-Slot: slot_75984b2e62e9
   


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