<@U0A71G31CDV> I'm testing 4.0.11 vs 4.1.4. I see ...
# questions-and-troubleshooting
a
@Rocky I'm testing 4.0.11 vs 4.1.4. I see around 40% performance degradation for the same queries in new version. what can be the reason?
r
When moving from StarRocks 4.0.11 to 4.1.4, a 40% performance degradation is significant. While 4.1 introduces many features aimed at high-concurrency and multi-tenant workloads, some of these involve architectural "trade-offs" that can impact raw single-query performance. Potential reasons for this degradation include: 1. Range Distribution and the "Colocate Join" Trade-off The most significant change in 4.1 is the introduction of Range Distribution and Adaptive Tablets. * The Trade-off: While Range Distribution improves QPS under high concurrency and handles data skew better, it disables Colocate Joins. In benchmarks, while high-concurrency throughput improved, single-user warm-cache queries were reported to be up to 2x slower because the optimizer could no longer perform joins locally without shuffling data. * What to check: Check if you have enabled
enable_range_distribution
(default is
false
). If you are using shared-data clusters, 4.1's new adaptive layout might be reshuffling data in ways that differ from your 4.0 setup. 2. Tablet Resharding and Parallelism Version 4.1 introduces a new "Large-Capacity Tablet" strategy (Phase 1). * Tablet Splitting: Tablets now automatically split when they exceed a target size (default 10GB). While this helps with ingestion and compaction, having a much larger number of tablets can sometimes lead to planning overhead or less efficient scan ranges if not tuned for your specific hardware. * Intra-tablet Parallelism: 4.1 introduced more aggressive intra-tablet parallelism. If your system is already CPU-bound, this extra parallelism might lead to resource contention rather than speedups. 3. Query Queue v2 and Resource Management Version 4.1 features Query Queue v2 and new resource isolation mechanisms. * Concurrency Control: If your 4.1 cluster is applying more restrictive queuing or resource limits than 4.0, your queries might be spending more time waiting or being throttled. * What to check: Compare the
Query Schedule
and
Wait
times in the Query Profile between the two versions. 4. Optimizer and Execution Changes * FULL OUTER JOIN ... USING: There was a semantics change in how these are handled in 4.1. * Simple Aggregation Rewrite: Ensure that
enable_rewrite_simple_agg_to_meta_scan
behavior is consistent, as regressions were noted in some 4.0.x versions that carried into 4.1 branches. * External Tables: If your queries hit Iceberg or Hive, 4.1 changed several default behaviors for metadata caching and native scanning (e.g., native C++ Avro scanner for Hive). Recommended Troubleshooting Steps: 1. Compare Profiles: Generate a Profile for the same query on both versions (
SET enable_profile = true
). Look for differences in: *
Join
type (Broadcast vs. Shuffle vs. Colocate). *
Scan
time and the number of tablets/ranges scanned. *
Wait
time in the query queue. 2. Verify Distribution Type: Run
SHOW CREATE TABLE
to ensure your tables are still using
DISTRIBUTED BY HASH
if you rely on Colocate Joins. 3. Check FE Configurations: Compare your 4.0 and 4.1 FE
fe.conf
and session variables, particularly those related to
enable_range_distribution
and
query_queue_v2
. If the degradation persists, it is highly recommended to post the comparison profiles in the StarRocks Slack community or open a GitHub issue, as 4.1.4 is a very recent release and there may be specific optimizer edge cases. References • release_notes/release-2.5.md • release_notes/release-2.3.md • release_notes/release-3.3.md • release_notes/release-2.4.md
a
@Rocky how to disable quey_queue_v2?
r
To disable Query Queue v2 and return to the legacy slot-based scheduler, or to disable the query queuing feature entirely, follow these steps: 1. Revert from V2 to Legacy Query Queue If you want to keep the query queuing feature but use the older scheduling logic (which was the default in 4.0), you must modify the FE configuration. This parameter is not a session variable and requires an FE restart. 1. Open your
fe.conf
file. 2. Add or modify the following line:
Copy code
properties
    enable_query_queue_v2 = false
3. Restart the FE for the change to take effect. 2. Disable Query Queuing Entirely If you want to stop queries from being queued at all (allowing them to run immediately until the system hits hard resource limits), you can do this dynamically via session variables without restarting: * To disable for the current session:
Copy code
sql
    SET enable_query_queue_select = false;
    SET enable_query_queue_load = false;
* To disable globally (for all new sessions):
Copy code
sql
    SET GLOBAL enable_query_queue_select = false;
    SET GLOBAL enable_query_queue_load = false;
Why this might affect your 4.1.4 performance: In v4.1,
enable_query_queue_v2
is enabled by default. It introduces more granular control over CPU and memory slots. If your 4.1 cluster is under heavy load or has lower default thresholds than your 4.0 setup, V2 might be "throttling" queries more aggressively by holding them in a
Pending
state. Note: You can check if queries are currently being queued by running
SHOW PROCESSLIST;
and looking at the
IsPending
column. If it is
true
, the query is waiting in the queue. References • administration/management/FE_configuration.md • faq/resource_isolation_faq.md • administration/management/resource_management/query_queues.md • administration/management/monitor_manage_big_queries.md • sql-reference/System_variable.md
a
@Rocky I disabled
enable_query_queue_v2
but see the same latency degradation, anything else to try to tweak?
r
If disabling
enable_query_queue_v2
did not restore performance, the issue likely lies in one of the architectural changes introduced in v4.1 that affect query planning or execution. Here are the most likely candidates for a 40% degradation when moving from 4.0.11 to 4.1.4: 1. Colocate Join vs. Range Distribution Even if you haven't explicitly enabled
enable_range_distribution
, v4.1 introduces Adaptive Tablets. If your tables were converted or if you are using the new range-based distribution, Colocate Joins are disabled. * The Impact: In benchmarks, queries that previously used Colocate Joins (local execution) were found to be ~2x slower in v4.1 because they were forced to use Shuffle Joins. * Action: Run
EXPLAIN <your_query>
and look for
COLOCATE
. If you see
SHUFFLE
where you expect a local join, check if your tables have been affected by the new distribution logic. Verify that the FE configuration
enable_range_distribution
is
false
. 2. Large-Capacity Tablet Parallelism (Shared-Data) If you are running on a shared-data (Cloud Native) cluster, 4.1 introduces "Phase 1" of large-capacity tablets (target 100GB). This changes how parallelism is handled inside a single tablet. * The Impact: New intra-tablet parallelism can lead to CPU "thrashing" if your
pipeline_dop
(Degree of Parallelism) is already high. In 4.0, parallelism was mostly across tablets; in 4.1, it's also within them. * Action: Try capping the parallelism for your session to see if it reduces overhead:
Copy code
sql
    SET pipeline_dop = 8; -- Or a lower value than your core count
3. Simple Aggregation MetaScan Regression There is a known regression in the
enable_rewrite_simple_agg_to_meta_scan
rule that surfaced in late 4.0.x and 4.1 branches. It can cause the optimizer to choose a sub-optimal plan for basic
COUNT
or
MIN/MAX
queries. * Action: Try disabling this optimization to see if it fixes the latency:
Copy code
sql
    SET GLOBAL enable_rewrite_simple_agg_to_meta_scan = false;
4. Skew Join v2 and Join Reordering Version 4.1 introduced Skew Join v2 and changes to the Cost-Based Optimizer (CBO). Sometimes the new version makes different decisions about join order or "Broadcast vs. Shuffle." * Action: Compare the
Physical Plan
in the Query Profile of both versions. Look for: * Changes in
Join Type
(e.g., Broadcast Join in 4.0 becoming a Shuffle Join in 4.1). * Differences in the order of tables being joined. 5. File Bundling (Shared-Data Only) Version 4.1 uses a new "File Bundling" strategy to reduce I/O calls to object storage. While this usually helps, it can occasionally cause higher latency during the "First Read" or if the local metadata cache is being heavily updated. * Action: Check the
Wait
and
Scan
metrics in your profile. If
RemoteScanTime
is significantly higher, it might be related to how the bundle metadata is being fetched. Summary Checklist to Tweak: Try running your test queries with these session variables to identify the culprit:
Copy code
sql
-- Revert to older aggregation behavior
SET enable_rewrite_simple_agg_to_meta_scan = false;

-- Force a specific DOP if CPU is saturated
SET pipeline_dop = <smaller_number>;

-- Check if Skew Join optimization is causing overhead
SET enable_skew_join_v2 = false;

-- If you are using external tables (Iceberg/Hive)
SET enable_connector_metadata_cache = true;
Next Step: The most effective way to solve this is to compare the Query Profile from 4.0.11 and 4.1.4. Specifically, look at the
TotalTime
of the
Scan
and
Exchange
operators. If
Exchange
time has increased, it's almost certainly a distribution/join strategy change. References • release_notes/release-4.0.md • release_notes/release-3.3.md
a
@Rocky I spend more time on checking performance and see extremely serious degradation for my case. I did test for 4.0.0 vs 4.1.4. Configurations in both cases is exactly the same i.e. I didn't tweak anything specifically for 4.1.4. Query I run is simple
Copy code
select sum(totals)
from schema.my_mv
where `date` >= '2025-06-01'
and id = 1234567
where
<http://schema.my|schema.my>_mv
is mat view that created from exact same source for both clusters and definition of MV is the same. I also double checked that number of rows is the same. 4.0.0 returns results in 0.5 sec 4.1.4 returns result in 1m 47s
r
A jump from 0.5s to 107s (a ~200x slowdown) for a direct scan on a Materialized View (MV) almost always indicates that Partition Pruning or Tablet Pruning has failed in v4.1.4, forcing the engine to perform a full scan of the entire MV instead of hitting a single tablet. In StarRocks 4.1.4, there are several architectural changes that could cause this: 1. Adaptive Layout and Range Distribution Version 4.1 introduces Adaptive Layout (specifically for shared-data/cloud-native clusters) and Range Distribution. * The Change: If your cluster has transitioned the table to Range Distribution, a query with
id = 1234567
may no longer be treated as a "point lookup" to a specific bucket if the metadata for those ranges is not yet optimized or if the optimizer chooses a wider scan. * Action: Run
SHOW CREATE TABLE schema.my_mv
. Check if the distribution has changed from
DISTRIBUTED BY HASH(id)
to something else. * Tweak: Try forcing hash-based behavior if it changed:
Copy code
sql
    SET enable_range_distribution = false;
2. Simple Aggregation MetaScan Regression There is a known performance regression in the MetaScan optimization rule that was enabled by default in late 4.0.x and 4.1.x. This rule tries to answer simple aggregations (like
sum
,
count
,
min/max
) using metadata only. If it miscalculates or fails to prune, it can become exponentially slower than a standard scan. * Action: Explicitly disable this optimization for your session:
Copy code
sql
    SET enable_rewrite_simple_agg_to_meta_scan = false;
3. Missing Partition/Tablet Pruning The most likely cause for a 100-second latency on a 0.5-second query is that the
date
or
id
predicates are not being pushed down to the storage layer. * Action: Run
EXPLAIN <your_query>
in both versions and compare the
OlapScanNode
section. * Look for
partitions=X/Y
and
tabletRatio=A/B
. * If 4.1.4 shows
partitions=ALL
or a much higher
tabletRatio
than 4.0.0, the pruning is failing. * Reason: v4.1 has stricter type matching for predicates. If
id
is a
VARCHAR
but you are passing an integer
1234567
(or vice-versa), 4.1.4 might skip Zone Map pruning or Bloom Filter usage that 4.0.0 handled more loosely. 4. Optimizer Statistics Change Version 4.1 uses a more sophisticated Cost-Based Optimizer (CBO). If the MV was created in 4.1.4 but statistics have not been collected, the optimizer might assume the table is tiny and choose a "Serial" execution plan (using only 1 BE or 1 thread) for what is actually a massive data scan. * Action: Manually trigger a statistics collection for the MV:
Copy code
sql
    ANALYZE TABLE schema.my_mv;
5. Large-Capacity Tablet Parallelism (Shared-Data) If you are on a Cloud Native cluster, 4.1.4 uses Large-Capacity Tablets (targeting 100GB). * The Impact: If the upgrade caused your data to be consolidated into very few, very large tablets, and the intra-tablet parallelism logic is not scaling correctly for your specific hardware, it could cause a massive bottleneck. * Action: Check if your
pipeline_dop
is set correctly. Try:
Copy code
sql
    SET pipeline_dop = 0; -- Let the system decide, or try a fixed number like 16
Summary of Tweaks to Try: Run your query after setting these variables:
Copy code
sql
-- Most likely fix for 'sum' scan regressions
SET enable_rewrite_simple_agg_to_meta_scan = false;

-- Force legacy distribution behavior
SET enable_range_distribution = false;

-- Ensure stats are fresh
ANALYZE TABLE schema.my_mv;

-- If using Cloud Native (Shared-Data), check if I/O is the bottleneck
SET enable_scan_block_cache = true;
If you can provide the output of
EXPLAIN ANALYZE <query>
from 4.1.4, the specific operator causing the 107s delay will be immediately obvious (look for the
Scan
node and check
PushdownPredicates
).
References • release_notes/release-4.0.md
a
@Rocky all Full analyze for my mv stuck in pending, why?
r
If your manual
ANALYZE TABLE
(Full Analyze) for a Materialized View is stuck in a PENDING state, it typically means the task has been submitted to the StarRocks statistics scheduler but hasn't been allocated a thread to run. Here are the most common reasons and how to fix them in v4.1.4: 1. Check if Statistics Collection is Enabled If the global switch for statistics collection is turned off, tasks will be created but will never transition from
PENDING
to
RUNNING
. * Check: Run
ADMIN SHOW CONFIG LIKE 'enable_statistic_collect';
* Fix: If it is
false
, set it to `true`:
Copy code
sql
    ADMIN SET FRONTEND CONFIG ("enable_statistic_collect" = "true");
2. Check the Scheduling Window StarRocks has a default time window for automatic statistics collection. While manual tasks should bypass this, in some versions, the scheduler thread itself remains idle outside these hours. * Check:
statistic_auto_analyze_start_time
and
statistic_auto_analyze_end_time
. * Fix: Ensure the current server time is within this range, or temporarily expand the window:
Copy code
sql
    ADMIN SET FRONTEND CONFIG ("statistic_auto_analyze_end_time" = "23:59:59");
    ADMIN SET FRONTEND CONFIG ("statistic_auto_analyze_start_time" = "00:00:00");
3. Concurrency Limits The statistics scheduler has a limited number of slots. If you have many tables or if the system is automatically trying to analyze many partitions after your upgrade, your manual task is simply waiting in line. * Tweak: You can increase the parallelism of the collection tasks (this is a session variable that affects how the task runs once it starts):
Copy code
sql
    SET statistic_collect_parallel = 4; -- Default is 1
* Check Queue: Run
SHOW ANALYZE STATUS;
(for manual tasks) or
SHOW ANALYZE JOB;
(for custom/auto tasks). If you see many tasks in
RUNNING
state, you must wait for them to finish. 4. Conflict with MV Refresh An asynchronous Materialized View cannot be analyzed while it is actively refreshing. * Check: Run
SHOW MATERIALIZED VIEWS LIKE 'your_mv_name'\G
. * Fix: If
last_refresh_state
is
RUNNING
, wait for the refresh to complete before the
ANALYZE
task can start. 5. FE Thread Pool Exhaustion In rare cases, the FE thread pool responsible for statistics might be stuck or saturated. * Action: Check the FE leader logs (
fe.log
). Look for any errors related to
StatisticExecutor
or
AnalyzeManager
. * Fix: If you see no progress at all on any tables, a restart of the Leader FE may be required to clear a stuck scheduler thread. Immediate Workaround: Asynchronous Mode If you ran the command and your terminal is hanging, you are in Synchronous Mode. Try running it in Asynchronous Mode so you can at least get your terminal back while the system queues it:
Copy code
sql
ANALYZE TABLE schema.my_mv WITH ASYNC MODE;
Then monitor it with:
Copy code
sql
SHOW ANALYZE STATUS WHERE `Table` = 'my_mv';
Recommendation: If it stays
PENDING
for more than 10 minutes and no other tasks are
RUNNING
, the most likely culprit is
enable_statistic_collect = false
or a restricted
statistic_auto_analyze
time window. References • using_starrocks/Cost_based_optimizer.md • administration/management/FE_configuration.md • sql-reference/sql-statements/cbo_stats/ANALYZE_TABLE.md • sql-reference/sql-statements/cbo_stats/SHOW_ANALYZE_STATUS.md References • knowledge/trouble_shooting/fe_deadlock_problems.md
a
@Rocky explain analyze for 4.1.4, same exact query against same exact mv takes <1s for 4.0.0.
Copy code
[0mSummary[0m
    [0mQueryId: 01a0b036-6211-7c18-9c9a-24d5509c02f5[0m
    [0mVersion: 4.1.4-4a9848e[0m
    [0mState: Finished[0m
    [0mTotalTime: 3m14s[0m
        [0mExecutionTime: 35.463ms [Scan: 5.763ms (16.25%), Network: 3.913ms (11.03%), ResultDeliverTime: 0ns (0.00%), ScheduleTime: 33.704ms (95.04%)][0m
        [0mCollectProfileTime: 0[0m
        [0mFrontendProfileMergeTime: 9.029ms[0m
    [0mQueryPeakMemoryUsage: ?, QueryAllocatedMemoryUsage: 3.623 GB[0m
    [0mTop Most Time-consuming Nodes:[0m
        [1m[31m1. OLAP_SCAN (id=0) : 18.039ms (74.19%)[0m
        [1m[38;2;250;128;114m2. EXCHANGE (id=3) [GATHER]: 4.475ms (18.40%)[0m
        [0m3. AGGREGATION (id=2) [serialize, update]: 1.156ms (4.75%)[0m
        [0m4. AGGREGATION (id=4) [finalize, merge]: 312.095us (1.28%)[0m
        [0m5. PROJECT (id=1) : 242.954us (1.00%)[0m
        [0m6. RESULT_SINK: 88.878us (0.37%)[0m
    [0mTop Most Memory-consuming Nodes:[0m
    [0mNonDefaultVariables:[0m
        [0mcharacter_set_results: utf8 -> NULL[0m
        [0menable_adaptive_sink_dop: false -> true[0m
        [0menable_async_profile: true -> false[0m
        [0menable_profile: false -> true[0m
        [0menable_rewrite_simple_agg_to_meta_scan: true -> false[0m
        [0mnew_planner_optimize_timeout: 3000 -> 30000[0m
        [0msql_mode_v2: 32 -> 2097184[0m
[0mFragment 0[0m
│   [0mBackendNum: 1[0m
│   [0mInstancePeakMemoryUsage: 484.156 KB, InstanceAllocatedMemoryUsage: 776.344 KB[0m
│   [0mPrepareTime: ?[0m
└──[0mRESULT_SINK[0m
   │   [0mTotalTime: 88.878us (0.37%) [CPUTime: 88.878us][0m
   │   [0mOutputRows: 1[0m
   │   [0mSinkType: MYSQL_PROTOCAL[0m
   └──[0mAGGREGATION (id=4) [finalize, merge][0m
      │   [0mEstimates: [row: 1, cpu: 8.00, memory: 8.00, network: 0.00, cost: 2686836.65][0m
      │   [0mTotalTime: 312.095us (1.28%) [CPUTime: 312.095us][0m
      │   [0mOutputRows: 1[0m
      │   [0mPeakMemory: ?, AllocatedMemory: ?[0m
      │   [0mAggExprs: [sum(37: sum)][0m
      │   [0mSubordinateOperators: [0m
      │       [0mLOCAL_EXCHANGE [Passthrough][0m
      └──[1m[38;2;250;128;114mEXCHANGE (id=3) [GATHER][0m
             [1m[38;2;250;128;114mEstimates: [row: 1, cpu: 8.00, memory: 0.00, network: 8.00, cost: 2686816.65][0m
             [1m[38;2;250;128;114mTotalTime: 4.475ms (18.40%) [CPUTime: 561.767us, NetworkTime: 3.913ms][0m
             [1m[38;2;250;128;114mOutputRows: 120[0m
             [1m[38;2;250;128;114mPeakMemory: ?, AllocatedMemory: ?[0m
             [1m[38;2;250;128;114mDetail Timers: [0m
                 [1m[38;2;250;128;114mOverallTime: 2.561ms [min=511.788us, max=3.973ms][0m
                 [1m[38;2;250;128;114mWaitTime: 2.437ms [min=450.992us, max=3.859ms][0m
[0m
[0mFragment 1[0m
│   [0mBackendNum: 20[0m
│   [0mInstancePeakMemoryUsage: 8.027 MB, InstanceAllocatedMemoryUsage: 3.622 GB[0m
│   [0mPrepareTime: 1.903ms[0m
└──[0mDATA_STREAM_SINK (id=3)[0m
   │   [0mPartitionType: UNPARTITIONED[0m
   └──[0mAGGREGATION (id=2) [serialize, update][0m
      │   [0mEstimates: [row: 1, cpu: 488508.92, memory: 0.80, network: 0.00, cost: 2686800.65][0m
      │   [0mTotalTime: 1.156ms (4.75%) [CPUTime: 1.156ms][0m
      │   [0mOutputRows: 120[0m
      │   [0mPeakMemory: ?, AllocatedMemory: ?[0m
      │   [0mAggExprs: [sum(35: total_count)][0m
      └──[0mPROJECT (id=1) [0m
         │   [0mEstimates: [row: ?, cpu: ?, memory: ?, network: ?, cost: ?][0m
         │   [0mTotalTime: 242.954us (1.00%) [CPUTime: 242.954us][0m
         │   [0mOutputRows: 15.484M (15484326)[0m
         │   [0mExpression: [35: total_count][0m
         └──[1m[31mOLAP_SCAN (id=0) [0m
                [1m[31mEstimates: [row: 244254, cpu: 4885089.18, memory: 0.00, network: 0.00, cost: 2442544.59][0m
                [1m[31mTotalTime: 18.039ms (74.19%) [CPUTime: 12.275ms, ScanTime: 5.763ms][0m
                [1m[31mOutputRows: 15.484M (15484326)[0m
                [1m[31mTable: my_mv[0m
                [1m[31mSubordinateOperators: [0m
                    [1m[31mCHUNK_ACCUMULATE[0m
                [1m[31mDetail Timers: [ScanTime = IOTaskExecTime + IOTaskWaitTime][0m
                    [1m[31mIOTaskExecTime: 2.097ms [min=644.738us, max=4.474ms][0m
                    [1m[31mIOTaskWaitTime: 532.377us [min=142.581us, max=2.072ms][0m
                    [1m[31mSubmitTaskTime: 6.022ms [min=3.918ms, max=8.763ms][0m
[0m
explain analyze output for 4.0.0
Copy code
[0mSummary[0m
    [0mQueryId: 01a0b041-e8f7-73e4-8be5-3834ec088828[0m
    [0mVersion: 4.0.0-dccb665[0m
    [0mState: Finished[0m
    [0mTotalTime: 674ms[0m
        [0mExecutionTime: 89.446ms [Scan: 12.447ms (13.92%), Network: 3.517ms (3.93%), ResultDeliverTime: 0ns (0.00%), ScheduleTime: 88.269ms (98.68%)][0m
        [0mCollectProfileTime: 2ms[0m
        [0mFrontendProfileMergeTime: 8.130ms[0m
    [0mQueryPeakMemoryUsage: ?, QueryAllocatedMemoryUsage: 3.661 GB[0m
    [0mTop Most Time-consuming Nodes:[0m
        [1m[31m1. OLAP_SCAN (id=0) : 24.002ms (81.48%)[0m
        [0m2. EXCHANGE (id=3) [GATHER]: 3.911ms (13.28%)[0m
        [0m3. AGGREGATION (id=2) [serialize, update]: 596.197us (2.02%)[0m
        [0m4. PROJECT (id=1) : 477.259us (1.62%)[0m
        [0m5. AGGREGATION (id=4) [finalize, merge]: 381.574us (1.30%)[0m
        [0m6. RESULT_SINK: 88.172us (0.30%)[0m
    [0mTop Most Memory-consuming Nodes:[0m
    [0mNonDefaultVariables:[0m
        [0malways_collect_low_card_dict_on_lake: false -> true[0m
        [0maudit_execute_stmt: false -> true[0m
        [0mcbo_prune_json_subfield_v2: true -> false[0m
        [0mcharacter_set_results: utf8 -> NULL[0m
        [0menable_adaptive_sink_dop: false -> true[0m
        [0menable_async_profile: true -> false[0m
        [0menable_lake_tablet_internal_parallel: true -> false[0m
        [0menable_materialized_view_agg_pushdown_rewrite_v2: true -> false[0m
        [0menable_profile: false -> true[0m
        [0mlow_cardinality_optimize_on_lake: false -> true[0m
        [0mnew_planner_optimize_timeout: 3000 -> 30000[0m
        [0msql_mode_v2: 32 -> 2097184[0m
[0mFragment 0[0m
│   [0mBackendNum: 1[0m
│   [0mInstancePeakMemoryUsage: 208.891 KB, InstanceAllocatedMemoryUsage: 396.375 KB[0m
│   [0mPrepareTime: ?[0m
└──[0mRESULT_SINK[0m
   │   [0mTotalTime: 88.172us (0.30%) [CPUTime: 88.172us][0m
   │   [0mOutputRows: 1[0m
   │   [0mSinkType: MYSQL_PROTOCAL[0m
   └──[0mAGGREGATION (id=4) [finalize, merge][0m
      │   [0mEstimates: [row: 1, cpu: 8.00, memory: 8.00, network: 0.00, cost: 1209098.34][0m
      │   [0mTotalTime: 381.574us (1.30%) [CPUTime: 381.574us][0m
      │   [0mOutputRows: 1[0m
      │   [0mPeakMemory: ?, AllocatedMemory: ?[0m
      │   [0mAggExprs: [sum(37: sum)][0m
      │   [0mSubordinateOperators: [0m
      │       [0mLOCAL_EXCHANGE [Passthrough][0m
      └──[0mEXCHANGE (id=3) [GATHER][0m
             [0mEstimates: [row: 1, cpu: 8.00, memory: 0.00, network: 8.00, cost: 1209078.34][0m
             [0mTotalTime: 3.911ms (13.28%) [CPUTime: 393.893us, NetworkTime: 3.517ms][0m
             [0mOutputRows: 120[0m
             [0mPeakMemory: ?, AllocatedMemory: ?[0m
[0m
[0mFragment 1[0m
│   [0mBackendNum: 20[0m
│   [0mInstancePeakMemoryUsage: 6.298 MB, InstanceAllocatedMemoryUsage: 3.660 GB[0m
│   [0mPrepareTime: ?[0m
└──[0mDATA_STREAM_SINK (id=3)[0m
   │   [0mPartitionType: UNPARTITIONED[0m
   └──[0mAGGREGATION (id=2) [serialize, update][0m
      │   [0mEstimates: [row: 1, cpu: 219829.23, memory: 0.80, network: 0.00, cost: 1209062.34][0m
      │   [0mTotalTime: 596.197us (2.02%) [CPUTime: 596.197us][0m
      │   [0mOutputRows: 120[0m
      │   [0mPeakMemory: ?, AllocatedMemory: ?[0m
      │   [0mAggExprs: [sum(35: total_count)][0m
      └──[0mPROJECT (id=1) [0m
         │   [0mEstimates: [row: ?, cpu: ?, memory: ?, network: ?, cost: ?][0m
         │   [0mTotalTime: 477.259us (1.62%) [CPUTime: 477.259us][0m
         │   [0mOutputRows: 15.485M (15485413)[0m
         │   [0mExpression: [35: total_count][0m
         └──[1m[31mOLAP_SCAN (id=0) [0m
                [1m[31mEstimates: [row: 109914, cpu: 2198292.25, memory: 0.00, network: 0.00, cost: 1099146.13][0m
                [1m[31mTotalTime: 24.002ms (81.48%) [CPUTime: 11.554ms, ScanTime: 12.447ms][0m
                [1m[31mOutputRows: 15.485M (15485413)[0m
                [1m[31mTable: : my_mv[0m
                [1m[31mSubordinateOperators: [0m
                    [1m[31mCHUNK_ACCUMULATE[0m
                [1m[31mDetail Timers: [ScanTime = IOTaskExecTime + IOTaskWaitTime][0m
                    [1m[31mIOTaskExecTime: 3.513ms [min=1.170ms, max=12.158ms][0m
                        [1m[31mSegmentInit: 1.703ms [min=0ns, max=9.672ms][0m
                            [1m[31mColumnIteratorInit: 1.449ms [min=0ns, max=9.104ms][0m
                    [1m[31mIOTaskWaitTime: 463.737us [min=137.145us, max=2.030ms][0m
                    [1m[31mSubmitTaskTime: 4.978ms [min=3.214ms, max=7.653ms][0m
[0m
r
The profile you shared reveals a critical diagnostic: your query is not slow to execute (35ms), but it is stuck in the Frontend (FE) Planning phase for over 3 minutes. The fact that
ExecutionTime
is 35ms while
TotalTime
is 194s confirms that the FE is hanging during metadata fetching or query optimization. Combined with your observation that
ANALYZE
is stuck in
PENDING
, this indicates a metadata locking or resource contention issue in the FE. Here is how to fix the 3-minute planning bottleneck in v4.1.4: 1. Skip the Synchronous Freshness Check In StarRocks 4.1, querying a Materialized View (even directly) triggers a Freshness Check against its base tables. If your base tables have many partitions or are in an external catalog (Iceberg/Hive), this check can be extremely slow and block the FE. * The Fix: Allow the query to use the MV even if it hasn't verified freshness in the last hour.
Copy code
sql
    ALTER MATERIALIZED VIEW schema.my_mv SET ("mv_rewrite_staleness_second" = "3600");
* Alternative: Temporarily disable the MV rewrite logic to see if planning time drops instantly:
Copy code
sql
    SET enable_materialized_view_rewrite = false;
2. Disable Query-Triggered Analyze Version 4.1.x enables
enable_query_trigger_analyze
by default. If the optimizer sees missing stats (which your profile confirms: Estimate 244k vs Actual 15M), it will attempt to trigger an
ANALYZE
task. If the statistics scheduler is stuck or saturated, the query might wait on a metadata lock. * Action: Disable this background trigger to see if planning resumes:
Copy code
sql
    SET GLOBAL enable_query_trigger_analyze = false;
3. Resolve the "Pending" Analyze Tasks If
ANALYZE
is stuck in
PENDING
, it usually means the statistics scheduler is disabled or the time window is closed. * Check the Scheduler: Ensure stats collection is actually on.
Copy code
sql
    ADMIN SHOW CONFIG LIKE 'enable_statistic_collect';
* Check the Time Window: By default, auto-analyze only runs at night. Manual tasks can sometimes be queued behind auto-tasks. Expand the window:
Copy code
sql
    ADMIN SET FRONTEND CONFIG ("statistic_auto_analyze_start_time" = "00:00:00");
    ADMIN SET FRONTEND CONFIG ("statistic_auto_analyze_end_time" = "23:59:59");
* Check Parallelism: If many tables were upgraded, the queue might be full.
Copy code
sql
    ADMIN SET FRONTEND CONFIG ("statistic_analyze_task_parallelism" = "4");
4. Metadata Cache (If base tables are External) If your MV is built on a Data Lake (Hive/Iceberg), 4.1.4 may be struggling to fetch metadata for the "Freshness Check." * Action: Ensure the connector metadata cache is active:
Copy code
sql
    SET GLOBAL enable_connector_metadata_cache = true;
Summary of what happened: The StarRocks 4.1.4 optimizer is likely attempting a "Strict Freshness" check or "Query-triggered Statistics" collection that is timing out or hanging due to a metadata lock. Because your
new_planner_optimize_timeout
is 30s but the query took 194s, the hang is occurring before the main optimization loop (likely during metadata retrieval). Try this first:
ALTER MATERIALIZED VIEW schema.my_mv SET ("mv_rewrite_staleness_second" = "3600");
This is the most common fix for massive planning regressions in 4.x when using MVs. References • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md • using_starrocks/Cost_based_optimizer.md • administration/management/FE_configuration.md • using_starrocks/async_mv/materialized_view_task_run_details.md References
a
@Rocky there is no parameters
statistic_analyze_task_parallelism
and
enable_connector_metadata_cache
r
I apologize for the incorrect parameter names. In StarRocks 4.1.x, some configuration names differ slightly from previous versions or documentation snippets. Your profile confirms the query execution itself is extremely fast (35ms), but the Planning phase (FE) is taking 3 minutes and 14 seconds. This delay and the stuck
ANALYZE
task are linked. 1. Correct Configuration Names for 4.1.4 Here are the actual parameters you should check and use in this version: * For Statistics Parallelism: This is a session variable, not a global FE config:
Copy code
sql
    SET statistic_collect_parallel = 4; -- Increase BE parallelism for the task
* For Metadata Caching: The parameters are catalog-specific. For Hive/Iceberg catalogs, use:
Copy code
sql
    -- Check if background refresh is enabled
    ADMIN SHOW CONFIG LIKE 'enable_background_refresh_connector_metadata';
* To Stop Planning Hangs (MV Freshness): The most common reason for a 3-minute planning delay on MVs is the Freshness Check against base tables. Disable it for your session to confirm:
Copy code
sql
    SET enable_materialized_view_rewrite = false;
If the query planning becomes instant after this, the delay is caused by StarRocks trying to verify if the MV is up-to-date with its base tables. 2. Why
ANALYZE
is stuck in
PENDING
If a manual
ANALYZE
is pending, the Statistics Scheduler is either disabled or saturated. Check these specific items: 1. Check the Master Switch:
Copy code
sql
    ADMIN SHOW CONFIG LIKE 'enable_statistic_collect';
    -- Must be TRUE. If FALSE, run:
    -- ADMIN SET FRONTEND CONFIG ("enable_statistic_collect" = "true");
2. Check the Status Reason: Run this to see why it is pending (look at the
Reason
column):
Copy code
sql
    SHOW ANALYZE STATUS WHERE `Table` = 'my_mv';
3. Check the Job Queue: Your cluster might be overwhelmed by "Query-Triggered" analyze tasks (a new feature in 4.x). Disable it to clear the queue:
Copy code
sql
    SET GLOBAL enable_query_trigger_analyze = false;
3. Immediate Fix for the 3-Minute Planning If you are querying the MV directly, you can bypass the slow freshness check by telling the optimizer to allow "stale" data (e.g., within the last hour):
Copy code
sql
-- Apply this to the MV itself
ALTER MATERIALIZED VIEW schema.my_mv SET ("mv_rewrite_staleness_second" = "3600");
Summary of what to run now: 1. Verify if Planning improves:
SET enable_materialized_view_rewrite = false;
then run your query. 2. Check Analyze state:
SHOW ANALYZE STATUS;
and check the
Reason
column. 3. Force start: Ensure
enable_statistic_collect
is
true
. Note: If your base tables are in an External Catalog (Iceberg/Hive), StarRocks 4.1.4 may spend minutes trying to reach the external Metastore (HMS/Glue) during the planning phase to check for updates. The
mv_rewrite_staleness_second
fix above is the primary solution for this. References • using_starrocks/Cost_based_optimizer.md • sql-reference/sql-statements/cbo_stats/SHOW_ANALYZE_STATUS.md • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md • administration/management/FE_configuration.md References • using_starrocks/Cost_based_optimizer.md
a
@Rocky I set
Copy code
SET statistic_collect_parallel = 4;
SET enable_materialized_view_rewrite = false;
ALTER MATERIALIZED VIEW schema.my_mv SET ("mv_rewrite_staleness_second" = "3600");
SET enable_materialized_view_rewrite = false;
latency is the same .. any other ideas on troubleshooting? I don't see big queue for analyze tasks, I hit full analyze for my mv and it is still running (very slow).
r
Since your
ExecutionTime
is only 35ms while
TotalTime
is over 3 minutes, the bottleneck is 100% in the Frontend (FE) planning phase. Specifically, the fact that
new_planner_optimize_timeout
is set to 30s but the query takes 190s suggests the hang is happening before the optimization loop (likely during metadata/statistics retrieval or while waiting for a lock). Because you've already tried the standard MV staleness settings, here are the deeper troubleshooting steps for StarRocks 4.1.4: 1. Identify "Slow Lock" Contention In StarRocks 4.x, the FE can sometimes experience lock contention when background
ANALYZE
tasks or metadata refreshes are running. * Action: Check the FE Leader logs (
fe.log
) for the keyword "Slow lock" or "DeadLockChecker". * Action: Run the following command during the "hang" to see if your query thread is waiting on a lock:
Copy code
sql
    SHOW PROC "/fe_locks";
If you see your query's ThreadId in a
WAITING
state, look at which ThreadId is holding the
EXCLUSIVE
lock (usually a metadata update or an Analyze task).
2. Disable Query-Triggered Analyze StarRocks 4.1.x introduced a feature that triggers statistics collection during the planning phase if stats are missing. Since your profile shows a massive estimate error (244k vs 15M), the FE is likely trying to trigger a background task or fetch stats that are currently being written by your slow
ANALYZE
job. * Fix: Disable this globally and try the query again:
Copy code
sql
    SET GLOBAL enable_query_trigger_analyze = false;
3. Check for Statistic Table Bloat If your internal statistics tables are very large, the FE can hang while trying to load the stats for your MV into its cache. * Check: See if the statistics table has an excessive number of rows:
Copy code
sql
    SELECT count(*) FROM _statistics_.column_statistics;
* Action: If this table has many millions of rows, it can slow down all planning. You may need to clean up old stats:
Copy code
sql
    DELETE FROM _statistics_.column_statistics WHERE table_id = <your_mv_table_id>;
4. Bypass CBO Statistics (Diagnostic) To prove the delay is caused by the FE trying to fetch/calculate statistics, disable the Cost-Based Optimizer's use of stats for one query: * Test:
Copy code
sql
    SET enable_stats = false;
    -- Run your query now
*If the query plans instantly (<1s), then the 3-minute delay is caused by the FE's Statistics Manager struggling to retrieve metadata for
my_mv
.* 5. Check Partition Count How many partitions does this MV have? In 4.1.4, if an MV has thousands of partitions, the FE may spend a long time performing "Partition Pruning" or checking the "Last Virgin Time" of each partition during planning. * Check:
SHOW PARTITIONS FROM my_mv;
* Fix: If you have >1000 partitions, consider merging them or reducing the retention period. 6. Kill the Slow Analyze Job If the
ANALYZE
is "Running" but very slow, it might be holding a metadata lock on the table, preventing the planner from finishing. * Action: 1. Find the job ID: `SHOW ANALYZE STATUS WHERE
Table
= 'my_mv';` 2. Kill it:
KILL ANALYZE <ID>;
3. Try the query again. Summary Recommendation The most likely culprit in 4.1.4 with this specific profile is contention between your manual
ANALYZE
and the FE's internal
Query-Triggered Analyze
logic.
1.
SET GLOBAL enable_query_trigger_analyze = false;
2.
KILL ANALYZE <id>;
(Kill any currently running jobs for that MV). 3.
SET enable_stats = false;
(To confirm if planning speed returns). If
SET enable_stats = false
fixes it, your statistics metadata is likely corrupted or the
_statistics_
table is too large for the FE to process efficiently. References • using_starrocks/Cost_based_optimizer.md
a
@Rocky there is no
enable_stats
param
r
To fix the 3-minute planning delay in StarRocks 4.1.4, we need to focus on why the Frontend (FE) is hanging before it even starts the execution. The fact that your query takes 3m14s while
new_planner_optimize_timeout
is only 30s means the hang is happening outside the main optimization loop—likely during metadata loading, statistics fetching, or while waiting for a lock. 1. Correct Parameter for Statistics I apologize for the confusion; the variable name in 4.x is
enable_cbo_statistics
(not
enable_stats
). To test if the hang is caused by the FE struggling to load statistics:
Copy code
sql
SET enable_cbo_statistics = false;
-- Now run your query
_If this makes the query plan instantly, then your
_statistics_
internal tables are likely bloated or corrupted._ 2. Check for FE Lock Contention In StarRocks 4.1, a common cause for long planning is lock contention between background
ANALYZE
tasks and user queries. While your query is hanging, run this in a separate terminal:
Copy code
sql
SHOW PROC "/fe_locks";
* What to look for: Look for your query's
ThreadId
in a
WAITING
status. * The Culprit: If another thread (often a
StatisticExecutor
or
RefreshMaterializedView
) is holding an
EXCLUSIVE
lock, it will block all query planning. 3. Disable "Query-Triggered" Analyze Version 4.x introduced a feature that triggers statistics collection when it detects missing stats (your profile shows a 15M vs 244k row mismatch). This can sometimes cause synchronous delays in planning.
Copy code
sql
SET GLOBAL enable_query_trigger_analyze = false;
4. Why your
ANALYZE
is slow/pending
If your manual
ANALYZE
is stuck in
PENDING
or is running very slowly, it is often due to the Statistics Scheduler being overwhelmed or the internal statistics table having too many versions. * Kill existing tasks: 1. `SHOW ANALYZE STATUS WHERE
Table
= 'my_mv';` 2.
KILL ANALYZE <ID>;
(Kill the stuck task). * Clear old stats: If the statistics table has millions of entries, it slows down the FE. You can try dropping the stats for that specific MV and recreating them:
Copy code
sql
    DROP STATS my_mv;
    ANALYZE TABLE my_mv WITH SAMPLE; -- Use sampled first for speed
5. Check "Freshness Check" Logic Even if you query the MV directly, StarRocks 4.1 performs a "Freshness Check" against base tables. If your base tables are very large or have many partitions, this check can be the bottleneck. * Confirm by disabling MV logic entirely for the session:
Copy code
sql
    SET enable_materialized_view_rewrite = false;
Note: If the planning is still slow with this set to false, then the issue is definitely Statistics or Metadata locks, not the MV logic. Summary Checklist: 1. Run
SET enable_cbo_statistics = false;
to see if planning becomes instant. 2. Check
SHOW PROC "/fe_locks";
during the 3-minute hang. 3. Run
SET GLOBAL enable_query_trigger_analyze = false;
to stop the FE from trying to auto-fix stats during your query. References • using_starrocks/Cost_based_optimizer.md • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md • sql-reference/sql-statements/cbo_stats/SHOW_ANALYZE_STATUS.md • administration/management/FE_configuration.md • best_practices/query_tuning/query_planning.md • using_starrocks/Query_planning.md
a
@Rocky there is no fe locks
Copy code
SHOW PROC "/fe_locks";
also
enable_cbo_statistics
doesn't exist
r
I apologize for the confusion regarding the parameter names. Based on the behavior you're seeing in StarRocks 4.1.4, here is the updated troubleshooting guide with the correct commands and system tables for this version. 1. Check Locks using the 4.1 System Table In StarRocks 4.1, the
SHOW PROC "/fe_locks"
command is being superseded by a system table. If you have
OPERATE ON SYSTEM
privileges, run:
Copy code
sql
SELECT * FROM sys.fe_locks;
Look for any threads in a WAITING state. If this table is empty, then a lock is likely not the cause of the 3-minute delay. 2. Disable the CBO Optimizer (Diagnostic) Since
enable_cbo_statistics
was not found, the most direct way to bypass all statistics-related planning in the FE is to disable the Cost-Based Optimizer (CBO) entirely for your session:
Copy code
sql
SET enable_cbo_optimizer = false;
-- Run your query now
* If the query plans instantly: The delay is caused by the FE's Statistics Manager (likely a slow lookup in the
_statistics_
table or a huge metadata load). * If it's still slow: The delay is caused by Metadata Retrieval (likely a timeout connecting to an external metastore or loading partition info). 3. Check for External Metastore Timeouts (3-Minute Hang) There is a known issue in StarRocks where the FE can hang for exactly 3 minutes if it fails to reach an external metastore (like Hive Metastore, Glue, or Iceberg REST) or if the connection is extremely slow. * Is your MV built on an External Catalog (Hive/Iceberg)? * If so, try bypassing the metadata cache and forcing a short timeout:
Copy code
sql
    -- Check for this variable in 4.1
    SET connector_metadata_ttl_s = 0;
4. Find the Correct Variable Names Because 4.1 has renamed or added several variables, you can find the exact name for any statistics or metadata variable available in your session by querying:
Copy code
sql
SELECT * FROM information_schema.session_variables 
WHERE VARIABLE_NAME LIKE '%stat%' OR VARIABLE_NAME LIKE '%meta%';
5. Why
ANALYZE
is slow for your MV
If a
FULL ANALYZE
is running very slowly, it is likely because: 1. Column Count: You are analyzing a very wide table. Try analyzing only the join/filter columns:
Copy code
sql
    ANALYZE TABLE my_mv (col1, col2) WITH SAMPLE;
2. Table Bloat: The internal
_statistics_
table might be massive.
Copy code
sql
    SELECT count(*) FROM _statistics_.column_statistics;
3. Query-Triggered Analyze: In 4.1, queries can trigger background analyze tasks. Disable this to prevent your manual analyze from competing with automatic ones:
Copy code
sql
    SET GLOBAL enable_query_trigger_analyze = false;
Summary of Next Steps: 1. Try
SET enable_cbo_optimizer = false;
to see if planning speed returns. 2. Check
SELECT * FROM sys.fe_locks;
during the hang. 3. Check
fe.log
on the Leader FE for
RESTException
,
Timeout
, or
HMS
errors—these are the most common causes of a 3-minute planning hang in the 4.1.x line. References • using_starrocks/Cost_based_optimizer.md • sql-reference/sql-statements/cbo_stats/SHOW_ANALYZE_STATUS.md • administration/management/FE_configuration.md • sql-reference/System_variable.md • using_starrocks/Query_planning.md • using_starrocks/query_acceleration_with_materialized_views.md • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md References
a
@Rocky
enable_cbo_optimizer
doesn't exists,
connector_metadata_ttl_s
doesn't exists as well. look through documentation and only respond with param name is matches doc. params I see in info schema
Copy code
cbo_prepare_metadata_thread_pool_size
cbo_push_down_aggregate_with_multi_column_stats
disable_table_stats_from_metadata_for_single_table
enable_collect_table_level_scan_stats
enable_delta_lake_column_statistics
enable_file_metacache
enable_hive_column_stats
enable_hive_metadata_cache_with_insert
enable_iceberg_column_statistics
enable_labeled_column_statistic_output
enable_metadata_profile
enable_paimon_column_statistics
enable_parallel_prepare_metadata
enable_query_queue_statistic
enable_rewrite_simple_agg_to_meta_scan
enable_stats_to_optimize_skew_join
hive_partition_stats_sample_size
max_unknown_string_meta_length
metadata_collect_query_timeout
r
Since
enable_cbo_optimizer
and
enable_stats
do not appear in your
information_schema.session_variables
, it confirms you are on a version (likely a 4.x or specific 3.3+ build) where these have been deprecated or renamed. The 3-minute planning delay vs. 35ms execution time points directly to a bottleneck in Metadata/Statistics retrieval. Based on the parameters you listed, here are the targeted troubleshooting steps: 1. Enable Metadata Profiling Since your planning is slow, you need to see which specific metadata call is hanging.
Copy code
sql
SET enable_metadata_profile = true;
SET enable_profile = true;
-- Run your query
After the query finishes, check the profile. You will see a new section under Planner called Metadata (or similar) that breaks down time spent on
getTable
,
getPartitions
, or
getColumnStats
. 2. Disable Stats Fetching from Metadata If your MV or its base tables have thousands of partitions/files, the FE may be hanging while trying to extract statistics directly from the storage metadata (e.g., Iceberg/Hive footers). * Fix: Use the variable you identified:
Copy code
sql
    SET disable_table_stats_from_metadata_for_single_table = true;
This forces the optimizer to use the internal
_statistics_
table instead of scanning file metadata. 3. Check/Adjust Metadata Collection Timeout You have
metadata_collect_query_timeout
. If your query is taking ~190s, it might be hitting this timeout (default is often 60s) multiple times for different tables or partitions. * Action: Try lowering this to see if the query fails faster (confirming the bottleneck):
Copy code
sql
    SET metadata_collect_query_timeout = 10;
4. Optimize Metadata Parallelism You have parameters to control how many threads the FE uses to fetch this data. If your MV is complex (many joins/unions), increasing these can help:
Copy code
sql
SET enable_parallel_prepare_metadata = true;
SET cbo_prepare_metadata_thread_pool_size = 16; -- Increase from default
5. Disable Specific Column Stats If the FE is hanging while trying to fetch column-level statistics for external catalogs (which MVs often use for "freshness" checks):
Copy code
sql
SET enable_hive_column_stats = false;
SET enable_iceberg_column_statistics = false;
6. Address the "Slow Analyze" If
ANALYZE TABLE my_mv
is very slow, it's usually because it's trying to scan every single column. * Diagnostic: Check if the internal statistics table is bloated:
Copy code
sql
    SELECT count(*) FROM _statistics_.column_statistics;
* Recommendation: If the table is huge, the FE will hang just trying to load the stats for your MV. Use a sampled analyze instead:
Copy code
sql
    ANALYZE TABLE schema.my_mv WITH SAMPLE PROPERTIES("statistic_sample_collect_rows" = "1000000");
Summary of Next Step Run the query with
SET enable_metadata_profile = true;
and
SET disable_table_stats_from_metadata_for_single_table = true;
. If the time drops significantly, the issue is the FE's attempt to calculate stats from the raw data/metadata instead of using the pre-collected statistics. References • sql-reference/System_variable.md • using_starrocks/Cost_based_optimizer.md • best_practices/query_tuning/query_profile_operator_metrics.md • administration/management/FE_configuration.md • using_starrocks/Query_planning.md References • using_starrocks/Cost_based_optimizer.md • administration/management/BE_configuration.md
a
@Rocky in profile I see this as a problem
Copy code
ExecPlanBuild[1] 2m44s
, what other places to check?
r
The fact that
ExecPlanBuild
takes 2m44s is the smoking gun. In StarRocks, this phase is the final step of planning where the FE transforms the optimized physical plan into executable Fragments (work units for BEs). Because this is happening after the optimizer finishes, it usually means the bottleneck is Metadata Retrieval or Fragment Generation, not the CBO logic itself. 1. Check for "Fragment Explosion" In your Query Profile, look for the
Fragment
count (usually near the top or bottom). * The Issue: If your query (or MV) has an extremely large number of
UNION ALL
branches or thousands of partitions, the FE can struggle to generate the fragments. * Fix: Check if you can use
SET enable_parallel_prepare_metadata = true;
to speed this up. 2. Materialized View "Freshness" Check Even when you query an MV directly, StarRocks 3.x/4.x checks if the MV data is fresh by comparing its version/timestamp with the base tables. * The Problem: If your base tables are in an External Catalog (Hive, Iceberg, Glue) and have thousands of partitions, the FE hangs during
ExecPlanBuild
while it recursively checks the metadata of every base table partition. * The Test: Bypass the freshness check to see if the plan builds instantly:
Copy code
sql
    -- This allows the query to use the MV regardless of base table changes
    SET query_including_mv_with_staleness = 1000000;
3. External Metadata Fetching Your list of variables includes
disable_table_stats_from_metadata_for_single_table
. During
ExecPlanBuild
, the FE may still be reaching out to fetch tablet locations (for internal tables) or file footers (for external tables). * Try this specific combination of your available params:
Copy code
sql
    SET disable_table_stats_from_metadata_for_single_table = true;
    SET enable_parallel_prepare_metadata = true;
    SET cbo_prepare_metadata_thread_pool_size = 16;
4. Check
fe.log
for "Full GC"
ExecPlanBuild
involves a lot of object creation in the FE's JVM. If your FE is low on memory, it may be spending 2+ minutes in a Stop-the-World Garbage Collection during this phase. * How to check: Search your
fe.gc.log
or
fe.log
for "Full GC" or "pause". * Solution: Increase the
JAVA_OPTS
heap size (e.g.,
-Xmx16g
) in
fe.conf
. 5. Check for "Internal Locks" (not in
sys.fe_locks
)
While
sys.fe_locks
shows database-level locks,
ExecPlanBuild
can wait on the StarRocks Catalog Lock if a heavy metadata operation (like a massive
LOAD
or
REFRESH MV
) is happening in the background. * Diagnostic: During the 2m44s hang, run a thread dump on the FE:
Copy code
bash
    jstack <FE_PID> > fe_stack.txt
Search for threads containing
ExecPlanBuild
or
Coordinator
and see if they are in
BLOCKED
or
WAITING
status. Summary: What to check in the Profile next Look closely at the indented lines under
ExecPlanBuild
. If you have
SET enable_metadata_profile = true;
enabled, you should see sub-metrics like: *
getPartitions
*
getTable
*
getBackends
If one of those is high, you have a metadata bottleneck with your Catalog. References • best_practices/query_tuning/query_profile_operator_metrics.md • using_starrocks/Query_planning.md • administration/management/FE_configuration.md • faq/Sql_faq.md • sql-reference/System_variable.md • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md
a
@Rocky
enable_mv_planner
can help?
r
enable_mv_planner
is not recommended for general query performance and is unlikely to help with a delay in the
ExecPlanBuild
phase. What
enable_mv_planner
does:
This is a specialized internal flag (introduced in v3.2) used primarily for the creation and maintenance of Materialized Views. * Purpose: It tells the optimizer to use "Real-time MV rules" and "Stream implementation rules" (e.g., choosing
LogicalBinlogScanOperator
). * Behavior: It is usually toggled automatically by the FE when you run
CREATE MATERIALIZED VIEW
or when a background refresh task starts. * Risk: Enabling it for a standard SELECT query can cause the optimizer to choose sub-optimal "stream-style" plans or binlog-based scans that are not intended for batch analytical queries. Why
ExecPlanBuild
is taking 2m44s:
Since
ExecPlanBuild
happens after the optimizer has finished its work, changing optimizer flags like
enable_mv_planner
won't address the bottleneck. This phase is where the FE turns the physical plan into "Fragments" and assigns them to BEs. A ~3-minute hang in
ExecPlanBuild
almost always indicates one of these three issues: 1. External Metadata Latency: If your MV is built on Hive, Iceberg, or Hudi, the FE is likely hanging while waiting for a response from the External Catalog (HMS or Glue) to get partition locations or file splits. * Check: Use
SET enable_metadata_profile = true;
and look for
getPartitions
or
getFileList
in the profile. 2. Fragment Explosion: If your query (or the MV definition) involves a massive
UNION ALL
or joins over thousands of partitions, the FE has to generate thousands of "Fragment Instances." This is a CPU and memory-intensive task for the FE's JVM. * Check: See the total number of fragments in your profile. If it's in the thousands, this is your bottleneck. 3. FE Garbage Collection: Building a massive plan creates millions of small objects in the FE's memory. If the FE is hitting its heap limit, it will experience "Stop-the-World" GC pauses right during
ExecPlanBuild
. * Check: Look at
fe.gc.log
for any "Full GC" entries matching the time of your query. Better Variables to Try: Instead of
enable_mv_planner
, try these which directly impact the planning of Materialized Views: *
enable_materialized_view_plan_cache = true
: If you run this query frequently, this will cache the resulting plan and skip the 2m44s build time entirely on subsequent runs. *
enable_parallel_prepare_metadata = true
: Forces the FE to fetch metadata for different tables/partitions in parallel (useful if external catalog latency is the issue). *
query_including_mv_with_staleness = 3600
: (If querying the MV) This tells the FE to skip the "freshness check" against base tables for 1 hour, which often bypasses the slow metadata calls during planning. Summary: Do not use
enable_mv_planner
. Focus on metadata profiling and FE memory if
ExecPlanBuild
is the specific bottleneck. References • sql-reference/System_variable.md • using_starrocks/async_mv/use_cases/query_rewrite_with_materialized_views.md • using_starrocks/async_mv/Materialized_view.md • using_starrocks/async_mv/feature-support-asynchronous-materialized-views.md
a
@Rocky
SET enable_metadata_profile = true;
only works for external tables, I don't see changes for MV based queries in profile.
query_including_mv_with_staleness = 3600
this one doesn't exists. my query is simple
select sum(total) from mv
. cluster has no load, so I run single query against big idle cluster. No cpu/memory spikes
r
The 2m44s in
ExecPlanBuild
for a simple
SELECT SUM(total) FROM mv
on an idle cluster strongly suggests the FE is struggling with a massive number of metadata objects (partitions or tablets) or a specific metadata check. Since
enable_metadata_profile
didn't provide details for the MV (it is indeed primarily for External Catalogs), and the staleness variable I mentioned earlier was a property rather than a session variable, let's use the parameters you confirmed exist in your system: 1. The Correct Staleness Variable The variable name depends on the version, but in newer versions (3.x+), the "staleness" is often handled via the MV property
mv_rewrite_staleness_second
. However, for a direct query on an MV, try this session variable to skip the "Is this MV consistent with base tables?" check during planning:
Copy code
sql
-- This variable exists in v3.1+ and might be in your schema as:
SET materialized_view_rewrite_mode = 'stale';
If this reduces the time, the FE was hanging while comparing the MV's partition versions against the base tables. 2. Parallelize Metadata Preparation Since you have these variables, use them. If your MV has a high partition/tablet count, the FE's single-threaded preparation is the likely bottleneck.
Copy code
sql
SET enable_parallel_prepare_metadata = true;
SET cbo_prepare_metadata_thread_pool_size = 16; -- Try 16 or 32
3. Check for "Tablet/Partition Explosion"
ExecPlanBuild
is the phase where the FE assigns specific Tablets to BEs. If your MV has a very large number of partitions or a high bucket count (e.g., thousands of partitions with 32 buckets each = 100,000+ tablets), the FE can hang just calculating the scan range. * Check: Run
SHOW PARTITIONS FROM your_mv;
and check the row count. If it's > 10,000, this is the issue. * Fix: If you don't need all data, use a
WHERE
clause to prune partitions. If you do need all data, consider recreating the MV with fewer partitions or lower bucket counts. 4. Bypass Metadata-based Stats You confirmed
disable_table_stats_from_metadata_for_single_table
exists. Even for internal MVs, the FE might try to derive "fresh" stats from the storage engine during planning.
Copy code
sql
SET disable_table_stats_from_metadata_for_single_table = true;
5. Materialized View Plan Cache If the query is always the same, you can bypass the "Build" phase entirely after the first run:
Copy code
sql
SET enable_materialized_view_plan_cache = true;
6. Verify FE Memory (The "Hidden" Bottleneck) Even if the cluster is idle, if the FE JVM Heap is nearly full, building a plan with many fragments/tablets will trigger massive "Partial GCs" that don't show up as CPU spikes but stop the FE threads. * Action: Check
log/fe.gc.log
. If you see GCs lasting several seconds during the query, you must increase
-Xmx
in
fe.conf
. Summary Recommendation Try this exact block to see if the 2m44s drops:
Copy code
sql
SET enable_parallel_prepare_metadata = true;
SET cbo_prepare_metadata_thread_pool_size = 16;
SET disable_table_stats_from_metadata_for_single_table = true;
SET materialized_view_rewrite_mode = 'stale'; -- Skip consistency check
SELECT sum(total) FROM your_mv;
If none of these work, the bottleneck is likely the sheer number of tablets in the MV. Check your bucket count (
DISTRIBUTED BY HASH(...) BUCKETS X
). If it's too high for the volume of data, it creates "metadata bloat" in the FE. References • sql-reference/System_variable.md • using_starrocks/async_mv/Materialized_view.md • administration/management/FE_configuration.md • using_starrocks/async_mv/feature-support-asynchronous-materialized-views.md
• best_practices/query_tuning/query_profile_operator_metrics.md • using_starrocks/Query_planning.md • faq/Sql_faq.md • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md • using_starrocks/query_acceleration_with_materialized_views.md • best_practices/query_tuning/query_plan_intro.md • best_practices/query_tuning/query_planning.md • using_starrocks/Cost_based_optimizer.md • best_practices/query_tuning/query_profile_text_based_analysis.md • sql-reference/sql-statements/cluster-management/plan_profile/EXPLAIN.md • sql-reference/sql-statements/cluster-management/plan_profile/EXPLAIN_ANALYZE.md • using_starrocks/query_profile_overview.md References • sql-reference/System_variable.md • using_starrocks/async_mv/feature-support-asynchronous-materialized-views.md • administration/management/FE_configuration.md • best_practices/query_tuning/query_planning.md • using_starrocks/async_mv/Materialized_view.md • using_starrocks/async_mv/use_cases/query_rewrite_with_materialized_views.md • using_starrocks/Materialized_view-single_table.md • using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md • using_starrocks/Cost_based_optimizer.md • administration/management/BE_configuration.md • administration/management/monitoring/metrics.md • best_practices/query_tuning/query_profile_operator_metrics.md • using_starrocks/Query_planning.md • using_starrocks/query_profile_overview.md • administration/management/FE_configuration.md • faq/Sql_faq.md • using_starrocks/async_mv/troubleshooting_asynchronous_materialized_views.md
a
@Rocky it still works for 4.0.0 <1s with 1:1 setup for mv in number of rows, partitions, tablets.
r
If
ExecPlanBuild
is fast (<1s) in one environment (v4.0.0) but slow (2m44s) in your current one with an identical setup, it confirms the bottleneck is in the FE's internal metadata processing logic or external communication, which has been optimized in newer versions. Since you've ruled out cluster load and resource spikes, here are the specific areas to check in your "slow" environment: 1. FE "Catalog Lock" Contention Even on an idle cluster,
ExecPlanBuild
must acquire a lock on the FE's internal Catalog to fetch tablet locations and partition versions. * What to check: Check
fe.log
for any warnings related to "lock" or "slow execution". * The Difference: In newer versions (like v3.3+ and the upcoming v4.0), StarRocks has moved towards more fine-grained locking or lock-free metadata reads for planning. In older versions, a background metadata sync or a single heavy table could hold the global catalog lock, stalling the
ExecPlanBuild
phase. 2. Parallel Metadata Preparation The
ExecPlanBuild
phase involves fetching the locations for every tablet in the query. If your MV has many tablets, doing this sequentially is slow. * The Fix: Ensure these variables are enabled in your "slow" environment (they are likely default-on in v4.0):
Copy code
sql
    SET enable_parallel_prepare_metadata = true;
    SET cbo_prepare_metadata_thread_pool_size = 16;
* Why it matters: This allows the FE to use multiple threads to resolve tablet locations, which is critical if you have thousands of tablets. 3. MV Freshness/Consistency Check When you query an MV, the FE verifies if the MV data is consistent with the base tables. For a simple
SELECT sum(total) FROM mv
, this check happens during the planning/build phase. * The Problem: If the base tables are in an External Catalog (Hive, Glue, etc.), the FE may be hanging while waiting for the external metadata store to return partition versions. * The Test: Bypass this check to see if the build time vanishes:
Copy code
sql
    -- Try setting the consistency to LOOSE for the session
    SET query_including_mv_with_staleness = 3600;
    -- Or if using v3.x+
    SET materialized_view_rewrite_mode = 'stale';
4. Fragment/Thrift Serialization
ExecPlanBuild
is the final step where the FE serializes the plan into Thrift objects to send to the BEs. * What to check: Check the number of Fragments in the profile. If it's very high (e.g., thousands), the serialization process itself becomes a bottleneck. * The Difference: Newer versions have optimized the serialization of large plans and the way "Scan Ranges" (tablets) are grouped. 5. FE JVM Pause (Safe Points) "No CPU/Memory spikes" on the cluster doesn't mean the FE is healthy. A JVM can enter a "Safe Point" for operations like Revoke Bias or Code Cache cleanup, which pauses all threads but doesn't necessarily show as a CPU spike. * Action: Check the
fe.gc.log
for any
Pause
entries longer than a few seconds during the query window. Also, check if the FE heap is near its limit (even if not spiking, a nearly-full heap causes frequent short GCs that cumulative to minutes). Summary Recommendation Compare the Session Variables of the fast v4.0 environment with your slow one:
Copy code
sql
SHOW VARIABLES;
Specifically, look for differences in: •
enable_parallel_prepare_metadata
•
enable_materialized_view_plan_cache
(This may be ON in v4.0, skipping the build entirely) •
metadata_cache_expiry_interval
If the environments are truly 1:1, the 2m44s is almost certainly the FE waiting for a Metadata Response (from an external catalog) or a Catalog Lock. References • best_practices/query_tuning/query_planning.md • using_starrocks/async_mv/feature-support-asynchronous-materialized-views.md
a
@Rocky how to speed up analyze for big table? I'm trying to do full analyze for my MV as last resort to speed up
r
Performing a Full Analyze on a massive table can be extremely slow because it triggers a full scan of all data. If you are doing this as a "last resort" to fix a 2m44s
ExecPlanBuild
delay, you should prioritize speed and targeted collection. Here are the best ways to speed up the
ANALYZE
process for a large Materialized View: 1. Increase Collection Parallelism By default, StarRocks runs statistics collection with low parallelism to avoid impacting query performance. You can crank this up for your session before running the command:
Copy code
sql
-- Default is 1. Increase to 8, 16, or more depending on your BE resources.
SET statistic_collect_parallel = 16;
2. Use
SAMPLE
instead of
FULL
For very large tables, a Sampled Analyze is often sufficient for the optimizer and is exponentially faster.
Copy code
sql
-- This will sample 2 million rows instead of scanning billions.
-- If 2,000,000 is still slow, try 500,000.
ANALYZE SAMPLE TABLE your_mv 
PROPERTIES("statistic_sample_collect_rows" = "2000000");
3. Analyze Only Relevant Columns If your query is a simple
SELECT sum(total) FROM mv
, the optimizer only needs stats for the
total
column. Analyzing the entire table (all columns) is a waste of time.
Copy code
sql
ANALYZE TABLE your_mv (total);
_Note: In StarRocks v3.5+, you can use
ANALYZE TABLE your_mv PREDICATE COLUMNS
to only collect stats on columns used in
WHERE
,
JOIN
, or
GROUP BY
clauses._ 4. Run in Asynchronous Mode If you don't want your SQL client to hang while waiting for the analyze to finish, run it in the background:
Copy code
sql
ANALYZE TABLE your_mv WITH ASYNC MODE;
You can check the progress with:
Copy code
sql
SHOW ANALYZE STATUS LIKE "your_mv%";
5. FE Configuration (If you have access) If the table is truly massive, the FE might split the analyze into too many small tasks. You can adjust these FE Configs (requires
ADMIN SET CONFIG
): *
statistic_collect_max_row_count_per_query
: (Default 5bn) If your table is larger than this, it splits the job. Increasing this allows larger chunks. *
statistic_max_full_collect_data_size
: (Default 100GB) Any table larger than this will automatically skip
FULL
and do
SAMPLE
unless you explicitly force
FULL
. Important Warning for
ExecPlanBuild
While
ANALYZE
helps the Optimizer choose between a Hash Join or NestLoop Join, it rarely speeds up the
ExecPlanBuild
phase. If
ANALYZE
finishes and the query still hangs for 2+ minutes in
ExecPlanBuild
, the issue is likely: 1. Too many tablets: Check
SHOW TABLE STATUS LIKE 'your_mv'
and look at the tablet count. If it's in the hundreds of thousands, the FE is struggling to map them to BEs. 2. Metadata locking: The FE might be waiting for a lock on the catalog. Recommendation: Try
ANALYZE SAMPLE TABLE your_mv (total) PROPERTIES("statistic_sample_collect_rows" = "1000000");
first. It should finish in seconds/minutes rather than hours. References • sql-reference/sql-statements/cbo_stats/ANALYZE_TABLE.md • using_starrocks/Cost_based_optimizer.md • sql-reference/System_variable.md • administration/management/FE_configuration.md • best_practices/query_tuning/query_planning.md • using_starrocks/Query_planning.md • sql-reference/sql-statements/cbo_stats/SHOW_ANALYZE_STATUS.md
a
@Rocky what is the implication of
SET statistic_collect_parallel = 1024;
? how to estomate what amount of resources it will take in cpus/memory?
r
Setting
statistic_collect_parallel = 1024
is an extremely aggressive configuration that can easily overwhelm a cluster. In StarRocks,
ANALYZE
is not a "background hint"—it is actually a series of distributed SQL-like queries that scan your table and perform aggregations (like
COUNT
,
MIN
,
MAX
,
NDV
). Here is the breakdown of what this setting implies and how to estimate the impact. 1. What does it actually do? When you run
ANALYZE TABLE
, the FE breaks the task down by columns and partitions. * Parallelism = 1 (Default): The FE submits one "statistics gathering" query at a time. It waits for the stats of Column A to finish before starting Column B. * Parallelism = 1024: The FE will attempt to fire off up to 1,024 concurrent sub-tasks to the BEs. If your table has 50 columns and 100 partitions, it could potentially launch hundreds of concurrent scan fragments across the cluster. 2. Resource Implications CPU: "The Thrashing Risk" Each parallel task is an MPP fragment. StarRocks' execution engine is highly optimized for multi-core usage. * If your cluster has, for example, 10 BEs with 32 cores each (300 cores total), setting parallelism to 1024 means you are asking for 3.4x more concurrent tasks than you have physical cores. * Result: Instead of being faster, the CPU will spend excessive time on context switching. It can lead to "CPU saturation" where 100% of the CPU is used but progress is slow because tasks are fighting for cycles. Memory: "The OOM Risk" Each parallel scan requires memory for: * RPC Buffers: To send data between BEs. * Aggregation States: Specifically for NDV (Number of Distinct Values), which uses HyperLogLog (HLL) or Bitmaps. * Estimation: If one
ANALYZE
fragment for a specific column takes ~200MB of memory, 1,024 fragments would require ~200GB of RAM across the cluster. If this exceeds your
query_mem_limit
, the
ANALYZE
task will fail with an "Out of Memory" error or kill other running queries. IO & Network 1,024-way parallelism will saturate your disk IOPS and network bandwidth. If your data is on S3/Object Storage, you might hit S3 throttling limits. 3. How to Estimate Resources To estimate the footprint, run a manual "dry run" query on a single column:
Copy code
sql
-- Measure CPU and Memory for one typical column
SELECT 
    COUNT(*), 
    APPROX_COUNT_DISTINCT(your_column), 
    MIN(your_column), 
    MAX(your_column) 
FROM your_table;
1. Check the Query Profile for that query to see the Peak Memory Usage and CPU Time. 2. Estimation Formula: _
Total Memory = (Peak Memory of 1 task) _ (statistic_collect_parallel)
_
Total CPU Cores = (Cores per task) _ (statistic_collect_parallel)
4. Rocky's Recommendation Do not use 1024. It is likely that the FE or BE will hit safety limits (like
max_query_concurrency
) before reaching that number anyway. * For "Fastest Possible": Set it to the number of BE nodes or 2x the number of BE nodes. _ _Example (10 BEs):*
SET statistic_collect_parallel = 10;
* For "Big Table" speed: Instead of parallelism, use Sampling:
Copy code
sql
    ANALYZE SAMPLE TABLE your_mv
    PROPERTIES("statistic_sample_collect_rows" = "1000000");
This is almost always better than a
FULL
analyze with high parallelism because it reduces the IO work rather than just trying to do the IO faster. Warning: Setting this globally (
SET GLOBAL
) can cause background automatic updates to suddenly spike your cluster usage. Only set it in the specific session where you are running the manual
ANALYZE
. References • using_starrocks/Cost_based_optimizer.md • administration/management/FE_configuration.md • knowledge/usage/best-practice.md
a
@Rocky how to increate analyze job timeout? I see
Analyze job timeout exceeded
.
r
To resolve the "Analyze job timeout exceeded" error, you need to adjust either the session-level timeout or the FE global configuration, depending on your StarRocks version and how you are running the command. 1. For Manual
ANALYZE
(Session Level)
If you are running a manual
ANALYZE TABLE
command, StarRocks treats this as a query. * StarRocks v3.4.0 and newer: Use the
insert_timeout
variable. In newer versions, statistics collection is grouped with "INSERT-like" operations.
Copy code
sql
    SET insert_timeout = 3600; -- Set to 1 hour (unit: seconds)
    ANALYZE TABLE your_table;
* StarRocks versions older than v3.4.0: Use the standard
query_timeout
variable.
Copy code
sql
    SET query_timeout = 3600; -- Set to 1 hour (unit: seconds)
    ANALYZE TABLE your_table;
2. For Background/Auto Analyze (FE Configuration) If your automatic analyze tasks or background jobs are timing out, you must change the FE configuration. This requires an admin account. The relevant configuration is
statistic_collect_query_timeout
.
Copy code
sql
-- Check current value
ADMIN SHOW FRONTEND CONFIG LIKE 'statistic_collect_query_timeout%';

-- Increase to 1 hour (3600 seconds)
ADMIN SET FRONTEND CONFIG ("statistic_collect_query_timeout" = "3600");
_Note: If this configuration is not found in your version, check for
query_timeout
or use the session variables mentioned above._ 3. Recommended Approach for Big Tables Instead of just increasing the timeout, you can make the job finish faster by using Sampled Analyze. For the optimizer to work well, you usually only need a representative sample rather than a full scan of billions of rows.
Copy code
sql
-- This will be much faster and less likely to timeout
ANALYZE SAMPLE TABLE your_mv 
PROPERTIES(
    "statistic_sample_collect_rows" = "1000000"
);
Summary of Timeout Variables Version | Manual Session Variable | FE Global Config v3.4.0+ |
insert_timeout
|
statistic_collect_query_timeout
Older |
query_timeout
|
query_timeout
(default 300s) If you are still seeing the error after increasing these, check the
fe.log
to see if the job is failing due to an Out of Memory (OOM) error or RPC issues, which can sometimes be misreported as a simple timeout. References • administration/management/FE_configuration.md • sql-reference/System_variable.md
a
@Rocky I run jstack on FE during I running my query and see this
Copy code
Thread: starrocks-mysql-nio-pool-282
  - CPU time: 105 seconds
  - Elapsed: 300 seconds (5 minutes)
  - State: RUNNABLE (actively computing, not waiting)

  Stuck at:
  com.starrocks.planner.OlapScanNode.checkIfScanRangeNumSafe(OlapScanNode.java:900)
    ↳ called from addScanRangeLocations(OlapScanNode.java:759)
    ↳ during PlanFragmentBuilder.createPhysicalPlan (ExecPlanBuild phase)
r
The
jstack
trace you provided is very revealing. It shows that your FE is spending a massive amount of time (105s CPU time) in
OlapScanNode.checkIfScanRangeNumSafe
. This confirms that the bottleneck in your
ExecPlanBuild
phase is not related to missing statistics, but rather to Metadata Scale. Specifically, your query is targeting an excessive number of tablets. Why
checkIfScanRangeNumSafe
is slow
During the
ExecPlanBuild
phase, the FE takes the physical plan and prepares the specific "Scan Ranges" (assignments of tablets to BEs). 1. The Loop: The FE must iterate through every single tablet involved in the query to verify its location and ensure the total number of scan ranges won't overwhelm the system or the RPC layer. 2. The Bottleneck: If your Materialized View (MV) or base table has hundreds of thousands of tablets (due to too many partitions or too many buckets), this loop becomes a CPU-intensive operation for the FE. 3. The Result: Even if the query eventually runs, the "Planning" phase (specifically
ExecPlanBuild
) takes minutes because the FE is struggling to process the metadata for so many tablets. How to fix it (Statistics won't help here) Performing an
ANALYZE
will not fix this, as
ANALYZE
helps the optimizer choose the join type, but it doesn't reduce the number of tablets the FE has to map once the plan is chosen. You must reduce the tablet count: 1. Check your Tablet Ratio Run
EXPLAIN
on your query and look for the
OlapScanNode
section. Look at the `tabletRatio`:
Copy code
text
tabletRatio: 150000/150000  <-- This is a huge red flag
If this number is in the tens of thousands or higher, that is your problem. 2. Optimize Partitioning/Bucketing * Reduce Buckets: If your partitions are small (e.g., a few hundred MBs), they should only have 1-3 buckets, not 10-50. You may need to recreate the MV with a lower
DISTRIBUTED BY HASH(...) BUCKETS X
. * Partition Pruning: Ensure your query filter includes the Partition Key. If you are doing a full table scan on a table with 10,000 partitions, the FE must check all of them. 3. FE Configurations (The "Band-Aid") You can try to adjust these FE configurations to see if it bypasses or speeds up the check, but use caution as these safety limits exist to prevent FE Out-of-Memory (OOM) errors: *
max_query_tablet_num
: (Default varies, e.g., 5000 or 10000). If your query exceeds this, it might trigger different logic. *
max_scan_key_num
: This limits the number of scan ranges created. Summary The
jstack
confirms your FE is "crunching" metadata for too many tablets. 1. *Stop trying to `ANALYZE`*—it won't solve the
ExecPlanBuild
delay. 2. Check
tabletRatio
in
EXPLAIN
. 3. Reduce the number of tablets in your Materialized View by decreasing the bucket count or improving partition pruning. A healthy query typically hits fewer than 1,000–5,000 tablets. References • best_practices/query_tuning/query_planning.md • faq/Sql_faq.md • best_practices/query_tuning/query_profile_operator_metrics.md • release_notes/release-2.5.md • faq/loading/Loading_faq.md • knowledge/trouble_shooting/fe_deadlock_problems.md
a
@Rocky in 4.0.0 query with this numbers of partitions/tablets to hit takes <1s
Copy code
partitions=23577/23577
     tabletRatio=23577/235770
     cardinality=110286
     avgRowSize=20.0
is 4.1.4 specifically designed to be slower for this case? any flags to disable? I can't find
max_query_tablet_num
, is it correct name? What is the value should be for
max_scan_key_num
? from docs
indicating that the value in the be.conf file is used.
it looks like CN config, not FE. how this can help?
r
The
jstack
output you provided confirms that your FE is experiencing a performance cliff in the
checkIfScanRangeNumSafe
method. This is a known bottleneck in recent StarRocks versions (4.0.x/4.1.x) when a query hits an exceptionally high number of partitions. 1. Is 4.1.4 designed to be slower? No, it is not "designed" to be slower, but 4.x introduced a heap-safety check during the scan-range calculation to prevent FE memory exhaustion (OOM). The issue (tracked in StarRocks GitHub as #76978) is that this safety check originally ran once per physical partition rather than once per scan node. When you hit 23,577 partitions, the FE performs tens of thousands of redundant checks, burning CPU cycles in the loop you captured. While this logic is intended to protect the FE, at your scale (23k+ partitions), the overhead of the safety check itself becomes the bottleneck. 2. Flags and Correct Configuration Names The configuration you are looking for to control or bypass tablet/scan-range limits is usually one of the following: *
max_scan_key_num
(Session/FE Variable):
* What it does: It limits the number of scan key segments generated for a query. * How it helps FE: By default, if this is 1024, the FE tries to segment your scan into many small ranges. If you have 23k partitions, the FE is doing a lot of work to manage these ranges. Increasing this (e.g., to 10,000 or more) can sometimes reduce the segmentation overhead, but it may increase BE memory usage. * Value: Try
SET max_scan_key_num = 8192;
to see if planning time drops. *
tablet_max_scan_range_num
(FE Config):
* This is the FE global configuration that limits the total tablets a single query can hit. If your query is hitting 23k tablets and this limit is lower, the FE might be struggling with the error-handling or fallback logic. Check it via
ADMIN SHOW FRONTEND CONFIG LIKE 'tablet_max_scan_range_num';
. 3. Why
max_scan_key_num
is in
be.conf
but affects FE
You noticed the docs say it uses the value from
be.conf
. Here is why: * The BE uses this value to limit how many search keys it processes during the actual scan. * However, the FE must know this limit during the Planning (ExecPlanBuild) phase. The FE uses this number to decide how to "chop up" the query into fragments. * By setting the Session Variable
SET max_scan_key_num = ...
, you are telling the FE: "Ignore the BE's default safety limit and plan the query with this many ranges." Rocky's Recommendations 1. Upgrade Check: Ensure you are on the latest patch of 4.1.4+. Fixes for the
#76978
performance regression were integrated into the 4.x maintenance branch to make this check "once per scan node" instead of "once per partition." 2. Increase Session Timeout: Since your planning is taking minutes, the FE might time out before the BE even starts.
Copy code
sql
    SET query_timeout = 600; -- Give it 10 minutes to finish planning
    SET max_scan_key_num = 10000;
3. Address the Root Cause (Partition Count): Hitting 23,000+ partitions in a single query is a major anti-pattern in StarRocks. * Partition Pruning: Check if your query can be restricted to fewer partitions (e.g., a smaller date range). * Table Design: If a single query must hit 23k partitions, your partitions are likely too "small" (too much metadata for too little data). Aim for partitions that hold at least 1GB–10GB of data. Reference: • StarRocks Issue #76978 (FE scan-range heap-safety check performance) • sql-reference/System_variable.md
a
@Rocky
tablet_max_scan_range_num
doesn't exists
r
The configuration name you are looking for is
query_max_tablet_num
. The reason you might not have found it is that it is a Global FE Configuration, not a session variable. You cannot see it with `SHOW VARIABLES`; you must use
ADMIN SHOW FRONTEND CONFIG
. 1. Correct Configuration Name In StarRocks 4.1.x, the check in
checkIfScanRangeNumSafe
is governed by: * Name:
query_max_tablet_num
* Default: Usually
10000
(10k) or
20000
(20k). * Effect: If a query hits more tablets than this, StarRocks throws an error. To check and increase/disable it:
Copy code
sql
-- Check current value
ADMIN SHOW FRONTEND CONFIG LIKE 'query_max_tablet_num';

-- Set to 0 to disable the check entirely (recommended to bypass the slow loop)
-- Or set to 100000 to accommodate your 23,577 partitions
ADMIN SET FRONTEND CONFIG ("query_max_tablet_num" = "0");
2. Why it is slow in 4.1.4 The
jstack
confirms you are hitting a performance regression (often discussed in the community around versions 3.3–4.1). * The Problem: The
checkIfScanRangeNumSafe
method is meant to be a quick safety check. However, in some 4.x versions, due to how the planner was refactored, this method is called repeatedly (sometimes for every single scan range or tablet) during the
ExecPlanBuild
phase. * The Scaling Issue: When you have 23,577 partitions, the FE ends up running an $O(N)$ loop inside another loop, leading to the 105 seconds of CPU time you observed. * The "Analyze" Connection: When you run
ANALYZE
, it triggers a background query to sample data. That query hits the same planning bottleneck, exceeds the default
statistic_collect_query_timeout
, and fails. 3. Regarding your other questions: *
max_scan_key_num
: * Value: 1024 (Default). * Function: This limits how many "ranges" the FE creates for predicates (e.g.,
WHERE id IN (1..1000)
). * Why it says BE: The BE uses this to limit resource usage during the actual scan. However, the FE must respect this limit during planning. If your query has complex filters, you can try
SET max_scan_key_num = 10000;
, but it will not fix the slow
checkIfScanRangeNumSafe
loop. * Is 4.1.4 specifically slower? Yes, this specific safety-check loop became more expensive in the 4.x planner compared to 4.0.0. This is treated as a performance bug. Recommendation 1. Immediate Fix: Run
ADMIN SET FRONTEND CONFIG ("query_max_tablet_num" = "0");
. This should bypass the logic in your
jstack
trace and let the planning phase finish in milliseconds. 2. Long-term: Update to the latest 4.1.x patch (e.g., 4.1.5 or 4.1.6). Patches have been released to optimize this check so it only runs once per scan node, preventing the $O(N^2)$ slowdown. 3. Table Design: Hitting 23k partitions is extremely heavy for any OLAP engine's metadata layer. If possible, consolidate your data into fewer, larger partitions (aiming for 1GB-10GB per partition). References • administration/management/FE_configuration.md • sql-reference/System_variable.md • best_practices/query_tuning/query_planning.md • administration/management/BE_configuration.md • faq/Sql_faq.md References • administration/management/FE_configuration.md • faq/Deploy_faq.md
a
@Rocky I see error
Config 'query_max_tablet_num' does not exist or is not mutable
when try to change ``query_max_tablet_num`
r
The error you're seeing occurs because the configuration name in StarRocks is
max_query_tablet_num
, not
query_max_tablet_num
. Additionally, in many versions, this configuration is not mutable via the
ADMIN SET FRONTEND CONFIG
command (it is a static configuration), meaning it cannot be changed while the FE is running. 1. Correct Configuration Name The correct name for the FE configuration that governs the
checkIfScanRangeNumSafe
logic is:
max_query_tablet_num
2. How to change it Since you received an error that it is "not exist or is not mutable," you likely need to modify it in your
fe.conf
file and restart your FE(s). 1. Open
fe.conf
on your Leader FE (and Follower FEs). 2. Add or modify the following line:
Copy code
bash
    max_query_tablet_num = 100000
(Setting it to 100,000 should accommodate your 23,577 partitions plus any bucketing overhead.) 3. Restart the FE. 3. Verification After restarting, you can verify the value by running:
Copy code
sql
ADMIN SHOW FRONTEND CONFIG LIKE 'max_query_tablet_num';
Why this is happening The
jstack
you provided earlier showed that the FE is spending 105 seconds in
checkIfScanRangeNumSafe
. Even if you increase the limit, the slowness will still exist because the FE has to iterate through all 23,000+ tablets to perform the check. This is an $O(N)$ loop that is exceptionally slow at your scale. Recommendation: * Bypass the check: To stop the FE from burning CPU in this loop, setting a very high limit in
fe.conf
and restarting is the first step. * Fix the Schema: A query hitting 23,577 partitions is a major performance bottleneck for FE metadata management. If possible, consider using a coarser partitioning strategy (e.g., monthly instead of daily) or reducing the bucket count. Aim to keep the
tabletRatio
below 5,000–10,000 for healthy planning performance. * Update: If you are on an early 4.1.x release, consider moving to 4.1.5 or later, where optimizations were added specifically to reduce the overhead of this safety check. References • administration/management/FE_configuration.md • best_practices/query_tuning/query_planning.md • faq/Sql_faq.md • sql-reference/System_variable.md • administration/management/BE_configuration.md • faq/Deploy_faq.md References • administration/management/BE_configuration.md • faq/Deploy_faq.md • administration/management/FE_configuration.md • administration/management/resource_management/Query_management.md • sql-reference/System_variable.md
a
@Rocky error
Config 'max_query_tablet_num' does not exist or is not mutable
what is the exact name?
r
The error
Config 'max_query_tablet_num' does not exist or is not mutable
indicates that you are likely trying to change a static configuration using the
ADMIN SET FRONTEND CONFIG
command. In StarRocks, static configurations can only be modified in the
fe.conf
file and require a restart to take effect. 1. The Exact Name The configuration governing the tablet limit and the
checkIfScanRangeNumSafe
logic you see in your jstack is indeed:
max_query_tablet_num
* Default: Usually
1000
or
2000
in older versions, but often increased in newer ones. * Mutability: It is not mutable via SQL in many 4.x versions. You must add/update it in your
fe.conf
and restart the FE. * Recommended Value: Since your query hits 23,577 tablets, set this to at least
30000
or
0
(to disable the limit, though disabling is not recommended for production stability). 2. Is 4.1.4 slower for this case? Yes. The 4.x series introduced more rigorous "heap-safety" checks during the planning phase to prevent FE OOMs when dealing with massive metadata. The bottleneck you captured in your jstack is a known issue where the check runs in a loop that scales poorly ($O(N)$) with the number of partitions/tablets. At 23k partitions, the overhead of just checking if the query is safe becomes the primary cause of the 100s+ delay. 3. Understanding
max_scan_key_num
* What it is: This limits how many individual "ranges" (scan keys) the FE generates for predicates like
WHERE id IN (1, 2, ... 10000)
. * Why it's both FE and BE: While the BE uses the value from
be.conf
to protect its own resources during execution, the FE needs to know this limit during Planning. If the FE generates more scan keys than the BE is configured to handle, the query will fail at runtime. * How it helps: By setting the Session Variable
SET max_scan_key_num = 10000;
, you are telling the FE: "I am overriding the BE's default safety limit; please plan the query with up to 10,000 ranges." * Recommendation: For your case,
max_scan_key_num
is likely not the main bottleneck; the sheer number of tablets (
max_query_tablet_num
) and the loop you found in the jstack are. Summary Checklist 1. Modify
fe.conf
: Add
max_query_tablet_num = 100000
to your
fe.conf
and restart the FE. This bypasses the immediate "too many tablets" error and can sometimes reduce the overhead if the limit was set too low. 2. Optimize Partitions: Hitting 23k partitions is an anti-pattern. If this is a time-series table, consider coarser partitioning (e.g., monthly instead of daily) or increasing the data volume per partition. Each partition adds metadata overhead to the FE. 3. Upgrade: If you remain on 4.1.4, you may continue to see slow planning for this specific table. Check for 4.1.5+ or 4.2.x releases, which contain optimizations for the
checkIfScanRangeNumSafe
method. To verify all available configuration names on your specific version, you can run:
Copy code
sql
ADMIN SHOW FRONTEND CONFIG;
Look for any entries containing
tablet
or
scan_range
. References • faq/Deploy_faq.md • administration/management/FE_configuration.md • administration/management/BE_configuration.md • sql-reference/System_variable.md
a
@Rocky I did rollback from 4.1.4 to 4.0.14 and latency is back to normal, however now I see issue with old task history (like from couple of days ago) adding back and no flags works anymore to stop. I tried
Copy code
ignore_task_run_history_replay_error=true
enable_task_history_archive=false
task_runs_ttl_second=86400
but records keep coming from very old runs
r
The rollback to 4.0.14 likely resolved the latency issue because it bypassed the 4.1.x planner regression you hit. However, the "reappearing" task history is a known side effect of rolling back between minor versions (4.1 → 4.0) where the task metadata format changed. The configurations you tried (
task_runs_ttl_second
, etc.) primarily control how the FE manages in-memory state and future archiving. They do not retroactively purge records that were already persisted in the internal storage using the 4.1 format during the time you were on the newer version. Why this is happening 1. Physical Storage: Task history is physically stored in an internal table:
_statistics_.task_run_history
. 2. Metadata Incompatibility: StarRocks 4.1 introduced changes to how tasks are archived and serialized. When you rolled back to 4.0.14, the FE encountered records in the
_statistics_
table (or the Edit Log) that were written by the 4.1 FE. 3. The "Replay" Effect: The 4.0 FE may be incorrectly interpreting these 4.1-formatted records or failing to apply the TTL cleanup logic to them because the version/format check fails. How to stop the "flood" of old records Since the FE configuration flags are not effectively cleaning the physical table, you must manually clear the history from the internal table. 1. Manually Clear the History Table Connect to your cluster and truncate the internal task history table. This will immediately clear the
information_schema.task_runs
view:
Copy code
sql
-- This clears all historical records of task runs
TRUNCATE TABLE _statistics_.task_run_history;
Note: This does not delete the Tasks themselves (definitions), only the history of their executions (TaskRuns). 2. Handle the "Analyze" history (Optional) If you are also seeing old "Analyze" (statistics) tasks re-running or appearing, clear that history as well:
Copy code
sql
-- If analyze history is also persistent and replaying
TRUNCATE TABLE _statistics_.analyze_status;
3. Adjust FE Configuration for Cleanup After truncating the table, ensure your FE is configured to aggressively clean up new records to prevent it from growing too large again:
Copy code
sql
ADMIN SET FRONTEND CONFIG ("enable_task_history_archive" = "true");
ADMIN SET FRONTEND CONFIG ("task_runs_ttl_second" = "86400"); -- 1 day
_If
enable_task_history_archive
is
true
, StarRocks will use a background thread to move finished tasks to the physical table and then purge them based on the TTL._ Summary of why your flags didn't work _ `enable_task_history_archive=false`: This stops the FE from writing new records to the table, but it doesn't delete the _old* records already in
_statistics_.task_run_history
. * `task_runs_ttl_second`: This only triggers a cleanup for records that the current FE version "understands" as valid history. Records written by 4.1 might be ignored by the 4.0 cleanup thread. * `ignore_task_run_history_replay_error`: This allows the FE to boot up and query the view despite corrupted/mismatched records, but it doesn't delete them. Final Recommendation: Run
TRUNCATE TABLE _statistics_.task_run_history;
. This is the standard "hard reset" for the task history state and should stop the old records from reappearing. References • administration/management/FE_configuration.md • sql-reference/information_schema/task_runs.md • administration/management/resource_management/Query_management.md • faq/Deploy_faq.md • sql-reference/System_variable.md References • administration/management/FE_configuration.md
a
@Rocky records continue to reappeart
r
The reason task history records continue to reappear even after you truncated the
_statistics_.task_run_history
table is that TaskRun history is stored in two places: the physical internal table (the archive) and the FE's in-memory metadata (replayed from the Edit Log). When you truncate the table, you only clear the archive. If those records were created while you were on version 4.1.4, they were likely written to the Edit Log. Every time you restart the FE or a follower syncs, it replays the Edit Log and reloads those "finished" task records back into memory, which then appear in
information_schema.task_runs
. To fully clear them and stop the "reappearing" behavior in version 4.0.14, follow these steps: 1. Force the In-Memory GC The FE has a background thread that prunes in-memory task history. If
enable_task_history_archive
is
true
, it relies on the table. To force it to clean its own memory, you should temporarily disable archiving and set the limits to zero. Run these on the Leader FE:
Copy code
sql
-- 1. Disable archiving so the FE uses in-memory TTL/Limit logic
ADMIN SET FRONTEND CONFIG ("enable_task_history_archive" = "false");

-- 2. Set history limit to 0 to force an immediate purge of memory
ADMIN SET FRONTEND CONFIG ("task_runs_max_history_number" = "0");

-- 3. Set TTL to a very low value (e.g., 1 second)
ADMIN SET FRONTEND CONFIG ("task_runs_ttl_second" = "1");
Wait 1–2 minutes for the background cleanup thread to run. 2. Check and Truncate again While the settings above are active, the FE should stop loading the old records into memory. Now, ensure the physical table is truly empty:
Copy code
sql
TRUNCATE TABLE _statistics_.task_run_history;
3. Trigger a Metadata Checkpoint (Optional but Recommended) Even if you clear memory, the "delete" events must be written back to the Edit Log, and a Checkpoint should be performed to truncate the physical BDBJE logs and save a new image. 1. Check the image directory on the Leader FE (
meta/image/
). 2. If a new image isn't generated within 15–20 minutes, you can force one (though there is no direct SQL command for this; it happens automatically based on
edit_log_roll_num
). 4. Restore "Healthy" Settings Once
information_schema.task_runs
is empty, restore your desired settings. If you want to keep history moving forward but prevent it from blowing up again:
Copy code
sql
ADMIN SET FRONTEND CONFIG ("enable_task_history_archive" = "true");
ADMIN SET FRONTEND CONFIG ("task_runs_max_history_number" = "10000");
ADMIN SET FRONTEND CONFIG ("task_runs_ttl_second" = "86400"); -- 1 day
Why the previous flags didn't work immediately: *
ignore_task_run_history_replay_error
: This simply prevents the FE from crashing or failing a query when it sees the "corrupted" 4.1.x formatted records. It does not delete them. *
enable_task_history_archive=false
: By setting this to
false
without also setting
task_runs_max_history_number=0
, the FE kept the existing records in memory and stopped trying to move them to the table for deletion. Note on Rollback Compatibility: StarRocks generally does not support "downgrading" metadata. By rolling back from 4.1 to 4.0, the FE is essentially "interpreting" 4.1 logs using 4.0 logic. This is why the task records are behaving unexpectedly. The steps above (forcing the limit to 0) are the best way to command the 4.0 logic to discard those replayed objects. References • administration/management/FE_configuration.md • sql-reference/information_schema/task_runs.md • administration/management/resource_management/Query_management.md • faq/Deploy_faq.md