Skip to content

[opt](point query) Optimize backend path collection for point queries - #67151

Open
zyp-V wants to merge 1 commit into
apache:masterfrom
zyp-V:op_point_query
Open

[opt](point query) Optimize backend path collection for point queries#67151
zyp-V wants to merge 1 commit into
apache:masterfrom
zyp-V:op_point_query

Conversation

@zyp-V

@zyp-V zyp-V commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Point-query planning built alive disk path sets for every backend even though tablet pruning leaves only a small set of replica backends. This made planning work grow with cluster size. Build the full map for regular scans and collect paths only for the selected tablet replica backends for point queries. Use the current backend snapshot API so the backport remains compatible with cloud and remote OLAP tables.

Release note

Reduce point-query planning overhead in clusters with many backends.

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Point-query planning built alive disk path sets for every backend even though tablet pruning leaves only a small set of replica backends. This made planning work grow with cluster size. Build the full map for regular scans and collect paths only for the selected tablet replica backends for point queries. Use the current backend snapshot API so the backport remains compatible with cloud and remote OLAP tables.

Backport of a209ce4b876c38aea0ea7d1f6c84e6e7b14c5a39.

### Release note

Reduce point-query planning overhead in clusters with many backends.

### Check List (For Author)

- Test: Unit Test
    - ./run-fe-ut.sh --run org.apache.doris.planner.OlapScanNodeTest#testPointQueryBackendAlivePathsOnlyUseSelectedTabletBackends
- Behavior changed: No. Only point-query planning work is reduced.
- Does this need documentation: No
@hello-stephen

Copy link
Copy Markdown
Contributor

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

Please clearly describe your PR:

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

@morrySnow morrySnow changed the title [improvement](fe) Optimize backend path collection for point queries [opt](point query) Optimize backend path collection for point queries Aug 26, 2026
@zyp-V

zyp-V commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@HonestManXin

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review result: request changes.

I found two actionable issues in the new point-query-only collection path:

  1. The helper and Tablet.getQueryableReplicas() can observe different replica snapshots after planning locks are released, allowing a newly published distinct-backend replica to bypass the dead-path tier.
  2. Cloud replicas have no disk path hash, but the helper still performs an additional compute-group/backend placement resolution whose result cannot affect cloud queryability.

Critical checkpoint conclusions:

  • Goal and proof: The patch does reduce stable local/remote point-query collection from all cluster backends to selected replica backends, and the regular-scan path remains unchanged. The new unit test correctly proves helper-level narrowing and alive/offline disk-set construction, but it does not cover the accepted concurrency interval or cloud call count.
  • Scope and clarity: The source change is focused, but the two issues above need correction before the optimization is safe and complete across supported modes.
  • Concurrency and lifecycle: New maps/sets are method-local and introduce no ownership, lock-order, or release problem. The material concurrency issue is the unlocked point-query reevaluation using two independently mutable LocalTablet snapshots.
  • Correctness and error handling: Visible-version checks, replica state/version checks, backend availability, resource tags, and downstream error propagation are otherwise preserved. Stable local/remote identity and missing-backend behavior match the previous path; cloud dynamic identity does not change disk-path correctness because CloudReplica.pathHash is always -1.
  • Compatibility and parallel paths: Non-point scans retain the full backend path map. Remote OLAP uses its catalog-scoped backend snapshot. No FE/BE protocol, storage-format, rolling-upgrade, configuration, persistence/EditLog, transaction, data-write, or master-failover change is involved.
  • Performance: The main asymptotic improvement is valid for local/remote point queries. The extra cloud resolution is nevertheless provably unused hot-path work; this review does not claim the whole PR is net slower than its baseline.
  • Tests and observability: Existing logs/retries remain available, but retry only mitigates the newly admitted dead-path candidate. Add a latch-based snapshot-publication test and a cloud resolution call-count test. No local build or test was run because the review runner instructions prohibit builds.
  • User focus: No additional focus point was supplied; the complete PR was reviewed.

Review convergence completed in two rounds. The second full review and both focused rechecks returned NO_NEW_VALUABLE_FINDINGS; no other unresolved issue remains.

Map<Long, Backend> backends, List<Tablet> tablets) {
Map<Long, Set<Long>> backendAlivePathHashes = Maps.newHashMap();
for (Tablet tablet : tablets) {
for (Replica replica : tablet.getReplicas()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Keep path filtering on the same replica snapshot

Point queries call lazyEvaluateRangeLocations() after the planning table lock has been released. This helper snapshots tablet.getReplicas() here, but Tablet.getQueryableReplicas() snapshots it again later. If a replica on a distinct backend B is added and receives its reported offline path between those reads, B is absent from this narrowed map; the later lookup gets null and treats B as a normal candidate. The previous full-backend map would have demoted B to deadPathReplica, so shuffle or fixed-replica selection can now put it ahead of a healthy replica (retry only mitigates that). Please carry one replica snapshot through both path collection and queryability filtering, and cover the two-stage publication interval with a latch-based test.

Map<Long, Set<Long>> backendAlivePathHashes = Maps.newHashMap();
for (Tablet tablet : tablets) {
for (Replica replica : tablet.getReplicas()) {
long backendId = replica.getBackendIdWithoutException();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Skip backend resolution for pathless cloud replicas

For a CloudTablet, this call dispatches through CloudReplica.getBackendId() and getCurrentClusterId(), including compute-group privilege/status/auto-start checks and potentially colocate or multi-replica backend scans. But CloudReplica always has pathHash == -1, so Tablet.getQueryableReplicas() never consults the alive-path set for it; the result built here is unused, and the downstream path resolves the backend again. This adds pure work to the latency-sensitive cloud point-query path. Please skip CloudReplica/CloudTablet in this disk-path helper, or resolve the cloud placement once and reuse it through scan-location construction; a cloud-mode call-count test would pin this behavior. (A generic pathHash == -1 skip would be unsafe for local replicas whose reported path is populated later.)

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16628 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 3f82c429e13d0641fad5de14fad279c862542728, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17555	3015	3015	3015
q2	2117	255	215	215
q3	10202	848	525	525
q4	4671	249	196	196
q5	7683	560	379	379
q6	136	120	95	95
q7	543	512	386	386
q8	9234	851	895	851
q9	3501	2431	2381	2381
q10	6506	851	719	719
q11	395	195	181	181
q12	647	260	196	196
q13	18099	1534	1162	1162
q14	160	148	139	139
q15	q16	435	389	367	367
q17	1270	825	769	769
q18	3074	2248	2205	2205
q19	1110	884	776	776
q20	370	279	197	197
q21	5282	1651	1888	1651
q22	326	271	223	223
Total cold run time: 93316 ms
Total hot run time: 16628 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3385	3355	3312	3312
q2	505	399	368	368
q3	2251	2401	2175	2175
q4	1194	1162	879	879
q5	2182	2113	2117	2113
q6	172	124	91	91
q7	1036	931	849	849
q8	1595	1397	1390	1390
q9	3111	3097	3072	3072
q10	1825	1789	1644	1644
q11	352	268	251	251
q12	447	424	335	335
q13	1483	1518	1166	1166
q14	174	172	167	167
q15	q16	388	394	353	353
q17	3641	3328	3305	3305
q18	4852	4409	4692	4409
q19	1393	814	943	814
q20	969	945	824	824
q21	3725	3030	3226	3030
q22	405	342	310	310
Total cold run time: 35085 ms
Total hot run time: 30857 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81550 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 3f82c429e13d0641fad5de14fad279c862542728, data reload: false

query5	4253	406	345	345
query6	420	132	121	121
query7	4924	374	231	231
query8	306	123	117	117
query9	8700	2834	2872	2834
query10	395	216	183	183
query11	5394	1015	940	940
query12	119	70	67	67
query13	1189	453	320	320
query14	6122	2187	2072	2072
query14_1	1954	1921	1942	1921
query15	181	121	115	115
query16	939	378	359	359
query17	820	448	362	362
query18	2343	330	238	238
query19	172	142	109	109
query20	70	69	72	69
query21	207	103	86	86
query22	5349	5330	5305	5305
query23	6620	6099	6076	6076
query23_1	5884	6180	5970	5970
query24	7306	1068	768	768
query24_1	775	794	775	775
query25	441	311	259	259
query26	963	228	132	132
query27	2775	390	253	253
query28	4697	1522	1510	1510
query29	929	447	362	362
query30	275	160	130	130
query31	841	410	327	327
query32	131	71	76	71
query33	500	208	170	170
query34	1003	839	499	499
query35	397	398	345	345
query36	573	529	536	529
query37	126	75	71	71
query38	1020	853	797	797
query39	488	493	452	452
query39_1	438	439	453	439
query40	197	87	77	77
query41	52	50	50	50
query42	73	71	74	71
query43	241	237	206	206
query44	1017	542	554	542
query45	107	104	95	95
query46	780	866	528	528
query47	743	746	692	692
query48	313	306	228	228
query49	545	228	185	185
query50	735	263	188	188
query51	7913	8026	8036	8026
query52	69	68	63	63
query53	191	196	144	144
query54	253	204	148	148
query55	70	59	61	59
query56	206	168	153	153
query57	681	668	656	656
query58	259	176	160	160
query59	1256	1222	1072	1072
query60	256	183	181	181
query61	118	118	113	113
query62	386	201	181	181
query63	168	141	143	141
query64	2286	648	563	563
query65	1602	1623	1554	1554
query66	1849	271	207	207
query67	10161	9764	9547	9547
query68	2775	1200	768	768
query69	396	215	198	198
query70	657	616	600	600
query71	248	167	162	162
query72	2394	1756	1544	1544
query73	671	603	327	327
query74	1573	1206	1130	1130
query75	1155	1095	939	939
query76	2302	736	559	559
query77	249	263	218	218
query78	3852	3687	3203	3203
query79	1350	911	562	562
query80	1204	335	290	290
query81	487	159	134	134
query82	676	136	103	103
query83	286	209	200	200
query84	306	118	92	92
query85	885	362	296	296
query86	441	170	174	170
query87	1001	967	884	884
query88	2774	2103	2102	2102
query89	297	194	172	172
query90	1979	127	128	127
query91	132	117	102	102
query92	78	63	66	63
query93	1383	1194	716	716
query94	673	256	218	218
query95	543	328	225	225
query96	810	587	281	281
query97	1035	1015	1043	1015
query98	145	133	133	133
query99	435	351	299	299
Total cold run time: 175240 ms
Total hot run time: 81550 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.43 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 3f82c429e13d0641fad5de14fad279c862542728, data reload: false

query1	0.01	0.00	0.00
query2	0.07	0.03	0.03
query3	0.25	0.11	0.10
query4	1.61	0.10	0.10
query5	0.17	0.16	0.16
query6	1.20	0.70	0.68
query7	0.04	0.01	0.00
query8	0.05	0.03	0.03
query9	0.31	0.21	0.22
query10	0.35	0.33	0.34
query11	0.16	0.11	0.12
query12	0.15	0.12	0.12
query13	0.29	0.30	0.31
query14	0.45	0.45	0.45
query15	0.36	0.35	0.34
query16	0.21	0.22	0.20
query17	0.68	0.63	0.65
query18	0.19	0.17	0.17
query19	1.24	1.18	1.08
query20	0.02	0.02	0.01
query21	15.44	0.17	0.12
query22	5.07	0.04	0.04
query23	16.14	0.25	0.10
query24	3.02	0.32	0.26
query25	0.12	0.03	0.05
query26	0.70	0.16	0.12
query27	0.03	0.03	0.03
query28	3.65	0.59	0.28
query29	12.44	3.14	2.52
query30	0.25	0.10	0.13
query31	2.76	0.37	0.17
query32	3.51	0.29	0.23
query33	1.51	1.43	1.40
query34	15.40	2.22	1.77
query35	1.77	1.71	1.71
query36	0.48	0.29	0.28
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.02	0.03
query40	0.11	0.08	0.07
query41	0.07	0.02	0.02
query42	0.03	0.02	0.02
query43	0.04	0.03	0.02
Total cold run time: 90.49 s
Total hot run time: 14.43 s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants