Skip to content

[improvement](fe) Reuse external scan tasks within a statement - #66530

Open
924060929 wants to merge 1 commit into
apache:masterfrom
924060929:fix/cir-21262-typed-scan-reuse-key
Open

[improvement](fe) Reuse external scan tasks within a statement#66530
924060929 wants to merge 1 commit into
apache:masterfrom
924060929:fix/cir-21262-typed-scan-reuse-key

Conversation

@924060929

@924060929 924060929 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary:

Queries with repeated equivalent external-table relations independently plan the same remote files for every branch, duplicating connector metadata work. The connector SPI already provides statement-scoped memoization (ConnectorStatementScope) for metadata, but scan planning was not memoized — each duplicate relation re-planned through the connector SDK.

This change adds statement-scoped scan reuse to all four connectors. Each builds a typed key from the facts that affect its split set:

  • Iceberg: table/snapshot/schema identity, predicate, case sensitivity, task type.
  • Paimon: relation/target identity, snapshot/schema, options, projection, predicate.
  • Hudi: query/incremental instant, reader mode, partition identity, runtime-prune mode, Hudi parameters.
  • Hive: catalog/table identity, immutable partition/file-listing inputs.

Equivalent scans reuse connector-native tasks within one statement execution. Iceberg streaming/lazy batch paths and transactional Hive paths remain uncached to preserve their memory and transaction semantics. Mutable Hudi/Hive scheduling objects are copied before use. ConnectorStatementScope.computeIfAbsent is widened from String to Object to accept typed keys directly.

Release note

Reuse equivalent Iceberg, Paimon, Hudi, and Hive scan-planning results within one statement execution.

Check List (For Author)

  • Test: Unit Test
    • IcebergScanPlanProviderTest
    • PaimonScanPlanProviderTest
    • HudiScanReuseKeyTest
    • ConnectorStatementScopeTest
    • 247 tests passed
    • Checkstyle clean
  • Behavior changed: Yes. Equivalent external scans reuse statement-scoped planning results; transactional Hive, streaming Iceberg, and system-table paths retain their previous behavior.
  • 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?

@924060929 924060929 changed the title [improvement](fe) Use typed keys with structural equals for scan reuse [refactor](fe) Replace string-encoded scan reuse keys with typed equals/hashCode Aug 6, 2026
@924060929 924060929 changed the title [refactor](fe) Replace string-encoded scan reuse keys with typed equals/hashCode [refactor](fe) Use typed equals/hashCode for scan reuse keys Aug 6, 2026
@morrySnow morrySnow changed the title [refactor](fe) Use typed equals/hashCode for scan reuse keys [refactor](scan) Use typed equals/hashCode for scan reuse keys Aug 6, 2026
@924060929 924060929 changed the title [refactor](scan) Use typed equals/hashCode for scan reuse keys [fix](fe) Fix scan reuse key aliasing and deduplicate key helpers Aug 6, 2026
@924060929 924060929 changed the title [fix](fe) Fix scan reuse key aliasing and deduplicate key helpers [refactor](fe) Replace string encoding with typed keys for scan reuse Aug 6, 2026
@924060929 924060929 changed the title [refactor](fe) Replace string encoding with typed keys for scan reuse [refactor](fe) Use typed objects instead of string encoding for scan reuse keys Aug 6, 2026
@924060929 924060929 changed the title [refactor](fe) Use typed objects instead of string encoding for scan reuse keys [improvement](fe) Statement-scoped scan reuse for Hive and Paimon, unify key approach Aug 6, 2026
@924060929 924060929 changed the title [improvement](fe) Statement-scoped scan reuse for Hive and Paimon, unify key approach [improvement](fe) Replace string-encoded scan reuse keys with typed equals/hashCode Aug 6, 2026
@924060929 924060929 changed the title [improvement](fe) Replace string-encoded scan reuse keys with typed equals/hashCode [improvement](fe) Reuse external scan tasks within a statement Aug 6, 2026
@924060929
924060929 force-pushed the fix/cir-21262-typed-scan-reuse-key branch from 141fd94 to cc165ac Compare August 6, 2026 07:04
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929
924060929 force-pushed the fix/cir-21262-typed-scan-reuse-key branch 2 times, most recently from 495ee54 to ab618f7 Compare August 6, 2026 08:23
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17729	3996	3931	3931
q2	2023	328	199	199
q3	10312	1407	799	799
q4	4685	475	338	338
q5	7535	868	563	563
q6	185	170	134	134
q7	765	790	620	620
q8	9313	1580	1590	1580
q9	5366	4125	4141	4125
q10	6736	1625	1332	1332
q11	501	352	328	328
q12	716	564	454	454
q13	18062	3306	2724	2724
q14	267	270	234	234
q15	q16	726	735	661	661
q17	992	1044	1007	1007
q18	6543	5590	5562	5562
q19	1299	1259	1042	1042
q20	823	661	595	595
q21	5945	2659	2475	2475
q22	447	348	297	297
Total cold run time: 100970 ms
Total hot run time: 29000 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4277	4234	4200	4200
q2	281	326	206	206
q3	4534	4893	4392	4392
q4	2178	2223	1406	1406
q5	4252	4097	4135	4097
q6	225	174	126	126
q7	1674	1591	1396	1396
q8	2767	2144	2128	2128
q9	7395	7493	7642	7493
q10	4272	4303	3886	3886
q11	546	419	373	373
q12	720	731	514	514
q13	3320	3476	2999	2999
q14	288	290	266	266
q15	q16	689	721	648	648
q17	1298	1301	1286	1286
q18	12099	10984	11794	10984
q19	1206	1148	1222	1148
q20	2218	2205	1971	1971
q21	5621	4824	4807	4807
q22	547	491	436	436
Total cold run time: 60407 ms
Total hot run time: 54762 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 166728 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 ab618f77680e4b572cff7534fd87c2ca04d150f5, data reload: false

query5	4310	600	441	441
query6	444	220	204	204
query7	4842	584	335	335
query8	319	192	146	146
query9	8776	4123	4063	4063
query10	487	356	313	313
query11	5788	2199	1995	1995
query12	173	96	99	96
query13	1296	585	438	438
query14	6103	4265	4040	4040
query14_1	3842	3832	3786	3786
query15	203	197	174	174
query16	1057	461	448	448
query17	888	666	547	547
query18	2471	470	323	323
query19	202	188	138	138
query20	100	98	102	98
query21	228	159	135	135
query22	13033	13011	13632	13011
query23	16196	15455	14889	14889
query23_1	14803	14514	14672	14514
query24	7565	1701	1231	1231
query24_1	1240	1246	1205	1205
query25	523	417	356	356
query26	1307	351	211	211
query27	2656	629	379	379
query28	4541	2044	2021	2021
query29	1052	613	491	491
query30	338	260	221	221
query31	1189	1125	1051	1051
query32	122	60	61	60
query33	548	308	257	257
query34	1202	1189	633	633
query35	752	758	619	619
query36	776	784	706	706
query37	162	112	90	90
query38	1827	1760	1683	1683
query39	848	823	801	801
query39_1	787	771	770	770
query40	261	172	147	147
query41	69	69	67	67
query42	94	93	92	92
query43	317	326	279	279
query44	1499	790	781	781
query45	191	174	162	162
query46	1072	1197	729	729
query47	1532	1516	1460	1460
query48	412	436	314	314
query49	597	413	296	296
query50	1065	455	346	346
query51	10579	10450	10549	10450
query52	90	90	79	79
query53	260	281	202	202
query54	290	253	238	238
query55	77	73	68	68
query56	318	307	316	307
query57	994	995	925	925
query58	295	274	269	269
query59	1573	1613	1393	1393
query60	340	289	272	272
query61	174	174	182	174
query62	402	329	279	279
query63	250	202	206	202
query64	3004	1201	851	851
query65	3862	3818	3776	3776
query66	1825	456	361	361
query67	28186	28125	27986	27986
query68	3202	1567	1037	1037
query69	395	299	262	262
query70	913	795	803	795
query71	381	353	312	312
query72	3044	2656	2375	2375
query73	817	766	458	458
query74	4623	4499	4293	4293
query75	2381	2333	2002	2002
query76	2337	1157	778	778
query77	333	392	270	270
query78	11278	11190	10530	10530
query79	1430	1168	770	770
query80	1234	536	457	457
query81	517	332	281	281
query82	672	181	133	133
query83	388	326	299	299
query84	331	158	131	131
query85	971	616	524	524
query86	401	240	226	226
query87	1982	1980	1841	1841
query88	3737	2819	2782	2782
query89	391	324	287	287
query90	2028	207	204	204
query91	207	193	164	164
query92	62	63	57	57
query93	1771	1526	974	974
query94	719	361	317	317
query95	795	504	565	504
query96	1063	875	353	353
query97	2483	2472	2308	2308
query98	195	184	204	184
query99	728	730	602	602
Total cold run time: 254491 ms
Total hot run time: 166728 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.05	0.05
query3	0.26	0.14	0.13
query4	1.61	0.14	0.14
query5	0.23	0.22	0.22
query6	1.16	0.82	0.83
query7	0.05	0.01	0.01
query8	0.06	0.04	0.04
query9	0.39	0.31	0.30
query10	0.60	0.54	0.54
query11	0.19	0.14	0.13
query12	0.18	0.14	0.14
query13	0.45	0.47	0.46
query14	0.99	1.00	0.99
query15	0.61	0.59	0.58
query16	0.33	0.31	0.33
query17	1.05	1.11	1.11
query18	0.21	0.19	0.20
query19	2.04	1.96	1.98
query20	0.02	0.02	0.01
query21	15.45	0.22	0.14
query22	4.78	0.05	0.05
query23	16.13	0.30	0.12
query24	3.01	0.43	0.32
query25	0.11	0.05	0.04
query26	0.72	0.20	0.14
query27	0.05	0.04	0.03
query28	3.58	0.80	0.35
query29	12.48	4.02	3.23
query30	0.27	0.15	0.16
query31	2.77	0.55	0.32
query32	3.22	0.58	0.48
query33	3.21	3.29	3.25
query34	15.47	3.91	3.26
query35	3.23	3.20	3.18
query36	0.54	0.41	0.41
query37	0.09	0.06	0.06
query38	0.05	0.04	0.03
query39	0.04	0.03	0.02
query40	0.17	0.16	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.03	0.03
Total cold run time: 96.08 s
Total hot run time: 23.96 s

@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: All Codex review accounts are usage-limited; earliest retry is 2026-08-08T03:32:00Z.
Workflow run: https://github.com/apache/doris/actions/runs/31142089772

Please trigger /review again after that time.

@924060929
924060929 force-pushed the fix/cir-21262-typed-scan-reuse-key branch from ab618f7 to 02b8284 Compare August 7, 2026 03:07
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: All Codex review accounts are usage-limited; earliest retry is 2026-08-08T03:32:00Z.
Workflow run: https://github.com/apache/doris/actions/runs/31143372312

Please trigger /review again after that time.

Replace string-encoded cache keys with typed key classes that use
Java's equals/hashCode for comparison. All ConnectorExpression
implementations already carry structural equals, so every key field
— filter conjuncts, partition lists, option maps, file scopes — is
stored as its natural Java type (List, Map, ConnectorExpression)
rather than an encoded String.

Changes:
- ConnectorStatementScope SPI: computeIfAbsent(String) -> (Object)
- 4 connector ScanReuseKey classes: add equals/hashCode, use raw types
- ConnectorScanKeyUtils: canonicalize only filter flattening
- Remove String.join(",") aliasing bugs (4 sites)
- Deduplicate canonicalFilter/stableMapToString helpers
- Update all ConnectorStatementScope implementations for new signature
- Fix ConnectorStatementScopeImpl javadoc for re-entrancy contract

The rewrite replaces the fe-core ExternalScanTaskCache prototype
(branch fix/cir-21262-iceberg-split-reuse) with the connector-SPI
approach already on master-test, eliminating ~400 lines of duplicate
infrastructure.
@924060929
924060929 force-pushed the fix/cir-21262-typed-scan-reuse-key branch from 02b8284 to a008699 Compare August 7, 2026 09:36
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17827	4048	3974	3974
q2	2125	316	198	198
q3	10282	1361	789	789
q4	4684	476	340	340
q5	7500	872	572	572
q6	183	172	138	138
q7	753	825	608	608
q8	9359	1547	1602	1547
q9	5311	4044	4012	4012
q10	6720	1636	1345	1345
q11	519	351	326	326
q12	702	578	458	458
q13	18115	3196	2745	2745
q14	271	259	244	244
q15	q16	744	732	658	658
q17	941	965	1062	965
q18	6577	5577	5569	5569
q19	1145	1315	1056	1056
q20	814	732	597	597
q21	5601	2663	2320	2320
q22	439	365	306	306
Total cold run time: 100612 ms
Total hot run time: 28767 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4296	4246	4187	4187
q2	294	319	210	210
q3	4552	4924	4335	4335
q4	2159	2246	1411	1411
q5	4216	4104	4143	4104
q6	232	172	131	131
q7	1729	1589	1445	1445
q8	2630	2353	2077	2077
q9	7488	7410	7539	7410
q10	4365	4269	3861	3861
q11	556	444	368	368
q12	721	730	535	535
q13	3070	3412	2881	2881
q14	301	297	261	261
q15	q16	690	740	670	670
q17	1340	1275	1309	1275
q18	12174	11056	11864	11056
q19	1207	1146	1197	1146
q20	2339	2231	1958	1958
q21	5584	4862	4929	4862
q22	546	480	454	454
Total cold run time: 60489 ms
Total hot run time: 54637 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 159489 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 a008699f135b2607b6fdb57f22ac3834cf9d5b66, data reload: false

query5	4340	580	460	460
query6	495	219	194	194
query7	4967	603	318	318
query8	333	167	145	145
query9	8799	4067	4051	4051
query10	489	380	298	298
query11	5854	2190	2046	2046
query12	158	99	97	97
query13	1250	572	426	426
query14	6088	4311	3993	3993
query14_1	3812	3856	3863	3856
query15	210	195	180	180
query16	1022	512	491	491
query17	1056	709	580	580
query18	2444	483	347	347
query19	231	191	156	156
query20	114	104	106	104
query21	234	159	133	133
query22	13120	13053	13694	13053
query23	16285	15424	14994	14994
query23_1	15078	14625	14791	14625
query24	7584	1690	1248	1248
query24_1	1290	1239	1220	1220
query25	562	424	350	350
query26	1299	366	214	214
query27	2632	612	366	366
query28	4568	2026	1999	1999
query29	1052	584	474	474
query30	341	259	216	216
query31	1162	1117	1062	1062
query32	108	55	58	55
query33	496	304	236	236
query34	1259	1161	636	636
query35	738	761	619	619
query36	770	798	681	681
query37	159	102	91	91
query38	1812	1757	1714	1714
query39	836	815	808	808
query39_1	800	767	789	767
query40	246	158	134	134
query41	62	62	58	58
query42	91	91	89	89
query43	313	323	273	273
query44	1438	758	776	758
query45	181	175	160	160
query46	1027	1169	741	741
query47	1521	1487	1439	1439
query48	406	395	295	295
query49	589	404	287	287
query50	1024	433	348	348
query51	10673	10623	10358	10358
query52	88	88	75	75
query53	270	280	208	208
query54	284	254	227	227
query55	74	73	66	66
query56	311	289	279	279
query57	995	971	911	911
query58	292	262	254	254
query59	1546	1555	1384	1384
query60	339	269	260	260
query61	160	153	153	153
query62	429	323	272	272
query63	233	198	192	192
query64	2841	1019	849	849
query65	3893	3819	3841	3819
query66	1823	457	376	376
query67	20098	20150	20221	20150
query68	3269	1637	1041	1041
query69	426	306	277	277
query70	898	779	812	779
query71	375	352	320	320
query72	3177	2805	2485	2485
query73	878	740	453	453
query74	4618	4513	4328	4328
query75	2363	2320	1979	1979
query76	2355	1153	751	751
query77	334	361	270	270
query78	11276	11243	10642	10642
query79	1503	1157	778	778
query80	1282	534	455	455
query81	525	338	283	283
query82	877	174	139	139
query83	382	331	303	303
query84	311	160	133	133
query85	992	610	540	540
query86	428	242	227	227
query87	1972	1985	1839	1839
query88	3713	2804	2780	2780
query89	419	315	294	294
query90	1904	205	190	190
query91	207	193	167	167
query92	64	59	56	56
query93	1716	1544	1084	1084
query94	728	357	311	311
query95	811	617	467	467
query96	1045	764	344	344
query97	2494	2451	2339	2339
query98	198	206	182	182
query99	739	737	612	612
Total cold run time: 247741 ms
Total hot run time: 159489 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.04	0.04
query3	0.26	0.13	0.14
query4	1.64	0.14	0.15
query5	0.24	0.22	0.21
query6	1.16	0.82	0.83
query7	0.04	0.02	0.01
query8	0.06	0.04	0.04
query9	0.37	0.31	0.30
query10	0.54	0.53	0.55
query11	0.20	0.14	0.14
query12	0.18	0.14	0.14
query13	0.47	0.46	0.48
query14	0.99	0.98	0.98
query15	0.62	0.58	0.60
query16	0.31	0.32	0.32
query17	1.05	1.07	1.05
query18	0.22	0.20	0.19
query19	2.02	1.97	1.97
query20	0.02	0.02	0.01
query21	15.46	0.19	0.13
query22	4.96	0.04	0.05
query23	16.14	0.30	0.13
query24	3.11	0.41	0.37
query25	0.12	0.06	0.04
query26	0.77	0.21	0.16
query27	0.05	0.04	0.06
query28	3.50	0.74	0.36
query29	12.53	4.02	3.15
query30	0.27	0.15	0.15
query31	2.78	0.55	0.32
query32	3.23	0.59	0.50
query33	3.19	3.18	3.20
query34	15.62	3.90	3.25
query35	3.23	3.21	3.28
query36	0.55	0.45	0.42
query37	0.09	0.07	0.06
query38	0.06	0.04	0.03
query39	0.04	0.03	0.03
query40	0.17	0.15	0.15
query41	0.08	0.03	0.04
query42	0.05	0.03	0.05
query43	0.04	0.04	0.03
Total cold run time: 96.54 s
Total hot run time: 23.88 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

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