Skip to content

feature(stats) Estimate scan cardinality from selected partitions for OLAP and external tables - #64032

Open
foxtail463 wants to merge 2 commits into
apache:masterfrom
foxtail463:improvement/selected-partition-row-count
Open

foxtail463 wants to merge 2 commits into
apache:masterfrom
foxtail463:improvement/selected-partition-row-count

Conversation

@foxtail463

@foxtail463 foxtail463 commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

Problem Summary

After partition pruning the optimizer still derived scan cardinality from table-level row counts, so external-table scans kept the unpruned table cardinality and OLAP scans double-applied partition predicates that remained in the plan for materialized-view rewrite, skewing join orderand cost estimates.

Solution

Add table-level selected-partition row count APIs (OLAP distributes unreported partition rows over the remaining partitions; external tables estimate from file listings within the selected set) and consume them in StatsCalculator, which now records the prunable partition conjuncts as conjunctsAppliedToRowCount so computeFilter no longer double-counts them while still narrowing their column domains against table-level statistics; the recorded proof is carried across scan slot rebinding and finally consumed by the PrunePartitionPredicate post-processor after MV rewrite, and external column statistics are proportionally scaled to the narrowed scan cardinality

@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

Copy link
Copy Markdown
Contributor

/review

@foxtail463
foxtail463 force-pushed the improvement/selected-partition-row-count branch from ad131d6 to 6b3af18 Compare June 3, 2026 12:16

@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 summary for PR 64032

I reviewed the partition-selection refactor across Nereids logical/physical OLAP and file scans, partition pruning, predicate post-processing, statistics, MV/HBO helpers, and Hive/Hudi/MaxCompute scan translation/runtime paths. I did not find a concrete blocking correctness issue to raise as an inline comment.

Critical checkpoint conclusions:

  • Goal and tests: The PR centralizes partition-selection state and extends selected-partition row-count handling for external scans. The changed tests cover logical/physical propagation, pruning behavior, and stats cases relevant to the refactor.
  • Scope/minimality: The change is broad but focused on replacing scattered selected-partition/prune flags with PartitionSelection abstractions and updating required call sites.
  • Concurrency/lifecycle: No new shared mutable state, lock ordering, or lifecycle-sensitive static initialization issue was found. New selection objects are immutable snapshots.
  • Config/compatibility: No new configuration, storage format, edit log, or FE-BE protocol compatibility change was found.
  • Parallel paths: OLAP, Hive/Hudi file scans, MaxCompute, physical translation, stats, and query partition collection were updated consistently.
  • Conditional checks: New conditions around partition-pruned/constraint state match prior semantics after tracing the old fields and runtime scan-node consumers.
  • Test coverage: Unit tests were added/updated for the main behavior touched. I did not run the test suite in this review environment.
  • Observability: Existing logging/profile paths remain sufficient for the changed planning/statistics paths; no missing mandatory metric/log was identified.
  • Transaction/persistence/data writes: The PR is planning/statistics-side only; no transaction or persisted metadata path change was identified.
  • Performance: The immutable snapshot approach avoids repeated mutable state hazards; no obvious pathological new hot-path scan or allocation issue was confirmed.

User focus points: No additional user-provided review focus was present.

@feiniaofeiafei

Copy link
Copy Markdown
Collaborator

run buildall

@foxtail463
foxtail463 force-pushed the improvement/selected-partition-row-count branch from 6b3af18 to 3a2808c Compare June 15, 2026 09:15
@foxtail463

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17793	4060	4003	4003
q2	q3	10789	1440	816	816
q4	4685	482	344	344
q5	7563	883	584	584
q6	186	176	138	138
q7	776	840	622	622
q8	9352	1684	1637	1637
q9	5856	4597	4477	4477
q10	6823	1791	1538	1538
q11	429	267	255	255
q12	626	430	297	297
q13	18129	3413	2806	2806
q14	276	261	245	245
q15	q16	832	781	714	714
q17	908	1001	976	976
q18	6916	5720	5700	5700
q19	1360	1322	1004	1004
q20	506	409	268	268
q21	5892	2637	2490	2490
q22	460	369	309	309
Total cold run time: 100157 ms
Total hot run time: 29223 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4331	4217	4275	4217
q2	q3	4570	4971	4334	4334
q4	2097	2222	1416	1416
q5	4422	4288	4320	4288
q6	232	175	129	129
q7	1740	1647	1774	1647
q8	2669	2228	2175	2175
q9	8103	8398	7883	7883
q10	4895	4767	4306	4306
q11	589	433	393	393
q12	771	748	549	549
q13	3304	3649	2957	2957
q14	319	321	274	274
q15	q16	695	752	665	665
q17	1364	1329	1343	1329
q18	8120	7271	7179	7179
q19	1172	1143	1102	1102
q20	2214	2223	1918	1918
q21	5316	4613	4464	4464
q22	527	448	415	415
Total cold run time: 57450 ms
Total hot run time: 51640 ms

@hello-stephen

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

query5	4303	626	478	478
query6	448	189	178	178
query7	4989	530	292	292
query8	362	208	199	199
query9	8818	4040	4032	4032
query10	438	315	248	248
query11	5862	2322	2168	2168
query12	165	100	95	95
query13	1256	621	421	421
query14	6385	5375	5038	5038
query14_1	4376	4324	4332	4324
query15	207	201	171	171
query16	992	450	405	405
query17	902	707	550	550
query18	2425	482	332	332
query19	205	180	137	137
query20	112	112	110	110
query21	214	131	113	113
query22	13671	13533	13413	13413
query23	17321	16625	16192	16192
query23_1	16238	16211	16177	16177
query24	7714	1772	1271	1271
query24_1	1338	1314	1347	1314
query25	567	472	397	397
query26	1300	337	171	171
query27	2744	544	332	332
query28	4485	2037	2036	2036
query29	1100	633	511	511
query30	323	241	194	194
query31	1120	1071	970	970
query32	107	60	61	60
query33	536	320	252	252
query34	1194	1122	670	670
query35	756	792	687	687
query36	1402	1385	1242	1242
query37	158	111	86	86
query38	3230	3123	3027	3027
query39	930	925	889	889
query39_1	890	875	867	867
query40	221	120	97	97
query41	64	62	61	61
query42	92	94	91	91
query43	314	317	283	283
query44	
query45	197	183	178	178
query46	1094	1251	744	744
query47	2375	2374	2196	2196
query48	388	431	300	300
query49	621	475	352	352
query50	1024	360	261	261
query51	4275	4432	4244	4244
query52	86	85	74	74
query53	241	265	187	187
query54	258	211	187	187
query55	80	75	69	69
query56	241	232	205	205
query57	1414	1415	1335	1335
query58	246	209	207	207
query59	1543	1601	1442	1442
query60	287	250	230	230
query61	159	152	148	148
query62	689	650	587	587
query63	229	185	189	185
query64	2533	737	613	613
query65	
query66	1775	453	342	342
query67	29352	29718	29619	29619
query68	
query69	428	295	259	259
query70	986	958	988	958
query71	297	225	209	209
query72	3002	2571	2275	2275
query73	865	753	441	441
query74	5128	4940	4760	4760
query75	2633	2583	2246	2246
query76	2328	1164	762	762
query77	351	378	285	285
query78	12518	12372	12026	12026
query79	1297	1010	780	780
query80	509	456	385	385
query81	442	280	244	244
query82	244	164	121	121
query83	268	279	261	261
query84	
query85	829	521	413	413
query86	337	307	281	281
query87	3366	3326	3220	3220
query88	3626	2771	2739	2739
query89	404	385	332	332
query90	2189	179	178	178
query91	168	158	130	130
query92	62	62	56	56
query93	1476	1610	864	864
query94	547	340	304	304
query95	675	369	430	369
query96	1120	822	334	334
query97	2683	2679	2566	2566
query98	211	203	200	200
query99	1134	1173	1019	1019
Total cold run time: 250022 ms
Total hot run time: 168995 ms

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 21.36% (289/1353) 🎉
Increment coverage report
Complete coverage report

Comment thread regression-test/conf/regression-conf.groovy
@foxtail463
foxtail463 force-pushed the improvement/selected-partition-row-count branch from 3a2808c to a4484e0 Compare June 15, 2026 13:26
@foxtail463

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 62.96% (294/467) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

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

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17655	4007	3978	3978
q2	q3	10746	1360	792	792
q4	4698	473	339	339
q5	7606	847	584	584
q6	203	168	135	135
q7	810	844	620	620
q8	10268	1613	1510	1510
q9	6824	4443	4433	4433
q10	6732	1803	1503	1503
q11	435	268	255	255
q12	636	427	293	293
q13	18149	3409	2759	2759
q14	263	260	239	239
q15	q16	811	764	705	705
q17	989	881	817	817
q18	6931	5776	5494	5494
q19	1284	1294	1027	1027
q20	508	403	261	261
q21	6053	2672	2391	2391
q22	433	349	309	309
Total cold run time: 102034 ms
Total hot run time: 28444 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4330	4248	4256	4248
q2	q3	4534	4925	4268	4268
q4	2069	2176	1404	1404
q5	4402	4277	4274	4274
q6	225	176	130	130
q7	1708	1599	1844	1599
q8	2590	2156	2259	2156
q9	7856	7845	7865	7845
q10	4786	4733	4316	4316
q11	613	419	383	383
q12	778	762	550	550
q13	3444	3672	2993	2993
q14	318	321	292	292
q15	q16	760	774	657	657
q17	1338	1326	1307	1307
q18	7931	7205	6997	6997
q19	1208	1118	1105	1105
q20	2225	2221	1950	1950
q21	5253	4556	4464	4464
q22	546	456	395	395
Total cold run time: 56914 ms
Total hot run time: 51333 ms

@hello-stephen

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

query5	4360	639	481	481
query6	447	207	167	167
query7	4878	552	313	313
query8	354	213	202	202
query9	8764	4091	4077	4077
query10	437	314	261	261
query11	5924	2347	2163	2163
query12	157	104	98	98
query13	1251	616	418	418
query14	6836	5420	5122	5122
query14_1	4445	4409	4447	4409
query15	206	199	179	179
query16	1011	452	404	404
query17	1119	713	603	603
query18	2700	489	337	337
query19	210	189	143	143
query20	112	111	108	108
query21	222	140	119	119
query22	13666	13705	13406	13406
query23	17335	16431	16122	16122
query23_1	16342	16195	16329	16195
query24	7491	1787	1329	1329
query24_1	1305	1302	1308	1302
query25	547	428	364	364
query26	1285	315	161	161
query27	2570	596	357	357
query28	4368	2094	2080	2080
query29	1097	589	479	479
query30	315	235	195	195
query31	1122	1073	961	961
query32	107	59	59	59
query33	523	319	250	250
query34	1152	1136	637	637
query35	752	764	676	676
query36	1387	1377	1241	1241
query37	152	104	87	87
query38	3201	3135	3066	3066
query39	936	929	888	888
query39_1	873	896	882	882
query40	223	118	104	104
query41	63	62	62	62
query42	95	93	92	92
query43	321	324	279	279
query44	
query45	198	185	181	181
query46	1056	1195	764	764
query47	2383	2369	2184	2184
query48	402	406	312	312
query49	638	483	336	336
query50	1006	358	266	266
query51	4299	4323	4220	4220
query52	87	88	76	76
query53	240	272	183	183
query54	272	213	199	199
query55	79	77	68	68
query56	228	222	225	222
query57	1433	1397	1318	1318
query58	238	206	213	206
query59	1559	1639	1388	1388
query60	285	229	231	229
query61	156	146	154	146
query62	707	646	585	585
query63	232	180	186	180
query64	2466	763	621	621
query65	
query66	1724	450	332	332
query67	29152	29729	29567	29567
query68	
query69	423	309	269	269
query70	998	977	973	973
query71	285	223	210	210
query72	2861	2615	2360	2360
query73	847	777	439	439
query74	5143	4947	4765	4765
query75	2668	2572	2250	2250
query76	2313	1180	807	807
query77	348	369	282	282
query78	12195	12338	11763	11763
query79	1323	1053	798	798
query80	575	460	394	394
query81	453	278	241	241
query82	563	161	124	124
query83	359	288	242	242
query84	
query85	837	534	420	420
query86	347	322	279	279
query87	3374	3417	3184	3184
query88	3641	2713	2720	2713
query89	410	387	339	339
query90	1866	183	184	183
query91	171	156	134	134
query92	65	63	56	56
query93	1491	1478	917	917
query94	546	361	309	309
query95	683	473	344	344
query96	1068	804	355	355
query97	2700	2695	2534	2534
query98	214	208	200	200
query99	1152	1169	1030	1030
Total cold run time: 249896 ms
Total hot run time: 168570 ms

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 62.53% (292/467) 🎉
Increment coverage report
Complete coverage report

@924060929

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 summary for PR #64032:

I reviewed the full FE/Nereids diff and the existing inline thread context. I did not find a new blocking correctness issue to raise in this pass.

Critical checkpoint conclusions:

  • Goal fit: The partition-selection refactor consistently carries selected partitions into OLAP/file scans and uses selected-partition row counts for stats where the row count is known.
  • Correctness: I checked the main semantic paths: OLAP partition pruning, file/Hive/Hudi/MaxCompute partition selection, physical translation, block-rule signaling, and filter selectivity skipping. The retained physical partition predicate for DELETE/skip-prune remains semantically redundant after partition pruning, so I did not treat that as a defect.
  • Plan/state propagation: Copy methods and logical-to-physical translators generally preserve PartitionSelection; places that intentionally narrow selected partitions keep the applied-predicate snapshot only for subsets.
  • Compatibility and persistence: No storage format, transaction log, FE-BE protocol, or compatibility issue found in the reviewed changes.
  • Concurrency/lifecycle: No new locking, async lifecycle, or resource-management risk found.
  • Security: This PR does not appear to change authentication, authorization, tenancy, or network-boundary behavior.
  • Tests: The PR adds focused unit coverage for selected-partition stats and predicate selectivity skipping. I did not run tests in this review runner.

User focus: .code-review.Uvi60a/review_focus.txt did not contain additional focus points, so there were no extra focus-specific findings.

@github-actions

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

Comment thread fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java Outdated
Comment thread fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java Outdated
Comment thread fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java Outdated
Comment thread fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSExternalTable.java Outdated
@foxtail463
foxtail463 force-pushed the improvement/selected-partition-row-count branch from a4484e0 to 08f1e9c Compare June 18, 2026 07:47
@foxtail463

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17694	4061	4079	4061
q2	2030	342	187	187
q3	10313	1471	838	838
q4	4679	479	343	343
q5	7534	896	589	589
q6	190	182	147	147
q7	797	839	630	630
q8	9373	1737	1642	1642
q9	5616	4544	4526	4526
q10	6754	1814	1538	1538
q11	443	283	250	250
q12	634	433	296	296
q13	18247	3382	2726	2726
q14	268	266	247	247
q15	q16	785	787	715	715
q17	1045	965	1040	965
q18	7083	5838	5777	5777
q19	1331	1300	1126	1126
q20	509	422	273	273
q21	5989	2795	2371	2371
q22	449	371	309	309
Total cold run time: 101763 ms
Total hot run time: 29556 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4514	4372	4420	4372
q2	335	347	233	233
q3	4614	4951	4412	4412
q4	2114	2205	1405	1405
q5	4494	4330	4383	4330
q6	243	187	134	134
q7	1758	2240	1760	1760
q8	2649	2291	2341	2291
q9	8503	8406	8413	8406
q10	4841	4764	4286	4286
q11	626	452	392	392
q12	809	785	538	538
q13	3252	3683	2950	2950
q14	297	305	284	284
q15	q16	714	735	682	682
q17	1383	1503	1359	1359
q18	7932	7564	7361	7361
q19	1246	1092	1101	1092
q20	2248	2269	1945	1945
q21	5305	4656	4537	4537
q22	551	470	400	400
Total cold run time: 58428 ms
Total hot run time: 53169 ms

@hello-stephen

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

query5	4363	645	472	472
query6	434	195	165	165
query7	4808	519	317	317
query8	356	211	192	192
query9	8739	4138	4110	4110
query10	431	319	254	254
query11	6010	2351	2137	2137
query12	252	103	96	96
query13	1261	596	419	419
query14	6335	5409	5065	5065
query14_1	4377	4352	4329	4329
query15	206	198	172	172
query16	1002	503	428	428
query17	1105	687	551	551
query18	2511	463	341	341
query19	208	200	140	140
query20	111	107	103	103
query21	213	137	140	137
query22	13707	13627	13294	13294
query23	17728	16520	16140	16140
query23_1	16241	16184	16306	16184
query24	7521	1776	1307	1307
query24_1	1335	1316	1312	1312
query25	538	422	381	381
query26	1290	316	163	163
query27	2689	556	345	345
query28	4481	2025	2026	2025
query29	1073	601	461	461
query30	308	236	197	197
query31	1128	1068	955	955
query32	108	59	55	55
query33	500	306	241	241
query34	1188	1154	657	657
query35	776	782	684	684
query36	1377	1375	1223	1223
query37	162	108	93	93
query38	1914	1726	1675	1675
query39	927	932	902	902
query39_1	891	874	875	874
query40	224	127	105	105
query41	70	67	67	67
query42	89	88	87	87
query43	322	323	282	282
query44	1449	784	768	768
query45	195	190	176	176
query46	1132	1227	760	760
query47	2363	2332	2270	2270
query48	385	432	306	306
query49	627	475	363	363
query50	983	371	272	272
query51	4433	4435	4465	4435
query52	85	83	72	72
query53	260	267	195	195
query54	289	224	210	210
query55	75	74	68	68
query56	270	233	238	233
query57	1440	1446	1323	1323
query58	258	225	244	225
query59	1582	1683	1419	1419
query60	293	256	240	240
query61	173	171	174	171
query62	705	647	606	606
query63	226	197	197	197
query64	2562	826	654	654
query65	4925	4820	4805	4805
query66	1826	488	351	351
query67	29869	29853	29776	29776
query68	3101	1637	1019	1019
query69	430	306	315	306
query70	1029	961	996	961
query71	301	227	200	200
query72	2950	2599	2287	2287
query73	849	738	460	460
query74	5138	5024	4742	4742
query75	2631	2613	2232	2232
query76	2344	1194	789	789
query77	346	389	296	296
query78	12403	12547	11934	11934
query79	1373	1161	793	793
query80	1267	454	375	375
query81	515	286	246	246
query82	573	160	121	121
query83	320	275	244	244
query84	264	144	116	116
query85	893	506	410	410
query86	436	295	293	293
query87	1824	1853	1773	1773
query88	3683	2789	2754	2754
query89	450	383	373	373
query90	1923	192	177	177
query91	174	155	130	130
query92	63	60	56	56
query93	1484	1539	916	916
query94	707	347	313	313
query95	693	455	341	341
query96	1031	781	337	337
query97	2703	2727	2579	2579
query98	217	205	201	201
query99	1170	1142	1005	1005
Total cold run time: 259365 ms
Total hot run time: 174057 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.10	0.05	0.04
query3	0.25	0.14	0.13
query4	1.60	0.15	0.14
query5	0.26	0.24	0.22
query6	1.27	1.22	1.10
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.38	0.31	0.31
query10	0.55	0.55	0.54
query11	0.19	0.15	0.14
query12	0.19	0.15	0.16
query13	0.47	0.49	0.47
query14	1.02	1.01	1.01
query15	0.63	0.60	0.62
query16	0.30	0.33	0.31
query17	1.13	1.08	1.10
query18	0.24	0.22	0.21
query19	2.00	1.97	1.93
query20	0.02	0.01	0.01
query21	15.49	0.20	0.14
query22	4.94	0.05	0.05
query23	16.14	0.31	0.12
query24	2.95	0.43	0.34
query25	0.12	0.05	0.05
query26	0.72	0.20	0.16
query27	0.04	0.03	0.05
query28	3.51	0.88	0.54
query29	12.49	4.33	3.49
query30	0.28	0.16	0.18
query31	2.78	0.61	0.32
query32	3.22	0.59	0.50
query33	3.17	3.20	3.22
query34	15.63	4.24	3.54
query35	3.57	3.57	3.52
query36	0.55	0.44	0.42
query37	0.10	0.07	0.07
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.09	0.04	0.03
query42	0.03	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.82 s
Total hot run time: 25.4 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 60.04% (269/448) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 53.29% (267/501) 🎉
Increment coverage report
Complete coverage report

@foxtail463

Copy link
Copy Markdown
Contributor Author

run nonConcurrent

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 47.51% (267/562) 🎉
Increment coverage report
Complete coverage report

@foxtail463

Copy link
Copy Markdown
Contributor Author

run nonConcurrent

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 33.50% (266/794) 🎉
Increment coverage report
Complete coverage report

@morrySnow morrySnow 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.

Review Summary

This PR introduces a PartitionSelection abstraction (65 files, +1424/-1075) to fix double-counting of partition predicates in Nereids row-count estimation. The core idea — compute scan row count from selected partitions, then tag Statistics with already-applied conjuncts so computeFilter can skip them — is sound and well-executed. The refactoring is comprehensive: all old-API callers are updated, all withXxx copy methods correctly carry the new state, and the physical plan translator wires all scan node types correctly.

Below are the issues found, ranked by severity:

1. [HIGH] MV/optStats early-return misses conjunctsAppliedToRowCount

File: fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java (around line 560)

The optStats.isPresent() early-return path returns derivedStats (from optStats.get()) directly without setting conjunctsAppliedToRowCount. The two other exit paths (partition-pruned and table-level) both set this field via the builder. When a Filter sits above this scan, computeFilter will re-apply the partition predicate selectivity to the already-pruned row count, producing a double underestimate.

Concrete failure: MV scan with partition pruning and stored optStats. The scan row count already reflects partition selection (e.g., 10M of 100M total). The Filter above applies the partition predicate again (×0.1 selectivity), reducing to 1M. The true row count should remain ~10M. This underestimation can cause wrong join order and aggregation strategy.

Suggested fix: Before returning, wrap in a StatisticsBuilder:

return new StatisticsBuilder(derivedStats)
    .setConjunctsAppliedToRowCount(
        olapScan.getPartitionSelection()
            .getAppliedPartitionConjuncts(olapScan, ((Plan) olapScan).getOutput()))
    .build();

2. [MEDIUM] buildSlotReplaceMap throws Preconditions.checkState — old code returned null gracefully

File: fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/PartitionSelection.java (new file)

The old PrunePartitionPredicate.buildSlotReplaceMap (deleted) returned null when a snapshot slot had no matching output slot, and the caller checked if (slotReplaceMap != null) to skip the entry. The new PartitionSelection.buildSlotReplaceMap throws IllegalStateException, which would crash query planning if column pruning removes a partition column from the scan output (the column is only referenced in WHERE, not SELECT).

Suggested fix: Restore the null-safe behavior.


3. [MEDIUM] computeFilter removes conjuncts by expression identity — fragile after rewrites

File: fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java (computeFilter method)

conjuncts.removeAll(inputStats.getConjunctsAppliedToRowCount()) uses Expression.equals() to match. If expression canonicalization produces a syntactically different but semantically equivalent form, removeAll silently fails to match, causing double-counting with no warning.


4. [LOW] LinkedHashSet allocation on every computeFilter call

File: fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java (computeFilter method)

Even when conjunctsAppliedToRowCount is empty (the common case), every call allocates a new LinkedHashSet. Guarding with isEmpty() would avoid overhead for the dominant path.


5. [LOW] PartitionPruner no longer records always-TRUE partition predicates

File: fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/PartitionPruner.java

When a partition predicate folds to BooleanLiteral.TRUE, the old code recorded it so the post-processor could strip it from the plan. The new code returns Optional.empty(), so these trivially-true predicates survive to BE execution — a minor optimization regression.


6. [LOW] isPruned() method vs partitionPruned field creates two-check inconsistency

Files: ExternalPartitionSelection.java, OlapPartitionSelection.java

Some callers check partitionSelection.partitionPruned directly, others call partitionSelection.isPruned(). These disagree when partitionPruned=true but all partitions survive. For OlapPartitionSelection, there is no isPruned() method at all — the equivalent check is done ad-hoc in computeOlapScan.

@foxtail463

Copy link
Copy Markdown
Contributor Author

run buildall

@foxtail463 foxtail463 changed the title [improvement](nereids) Estimate scan row count from selected partitions feature(stats) Estimate scan cardinality from selected partitions for OLAP and external tables Oct 1, 2026
@foxtail463
foxtail463 force-pushed the improvement/selected-partition-row-count branch from 4a8cd6a to 2f5157a Compare October 1, 2026 03:19
@foxtail463

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17658	3893	3876	3876
q2	2150	350	292	292
q3	10131	1322	782	782
q4	4685	483	344	344
q5	7454	831	532	532
q6	174	163	134	134
q7	733	790	605	605
q8	9337	1378	1510	1378
q9	5423	4225	4188	4188
q10	6825	1316	1039	1039
q11	436	264	239	239
q12	638	426	292	292
q13	18046	2624	1990	1990
q14	259	259	239	239
q15	q16	727	714	678	678
q17	1756	1137	1021	1021
q18	6479	5585	5537	5537
q19	1184	1207	1081	1081
q20	487	383	262	262
q21	5433	3076	2990	2990
q22	440	350	303	303
Total cold run time: 100455 ms
Total hot run time: 27802 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4671	4439	4519	4439
q2	716	572	550	550
q3	4777	5290	4586	4586
q4	2210	2346	1477	1477
q5	4569	4401	4569	4401
q6	232	175	129	129
q7	1767	1679	1468	1468
q8	2341	2190	2025	2025
q9	7363	6851	6818	6818
q10	3637	3561	3068	3068
q11	514	363	338	338
q12	723	700	498	498
q13	2292	2607	1985	1985
q14	264	280	241	241
q15	q16	658	689	608	608
q17	7290	6729	6648	6648
q18	11858	10993	11784	10993
q19	1109	1015	1015	1015
q20	2211	2176	1921	1921
q21	5033	4079	4266	4079
q22	507	441	392	392
Total cold run time: 64742 ms
Total hot run time: 57679 ms

@hello-stephen

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

query5	4306	615	474	474
query6	419	207	189	189
query7	4844	577	303	303
query8	339	200	167	167
query9	8799	3953	3952	3952
query10	447	315	281	281
query11	5832	3536	3233	3233
query12	150	93	87	87
query13	1266	603	452	452
query14	6505	4463	4193	4193
query14_1	3979	3916	3973	3916
query15	199	192	184	184
query16	1003	528	434	434
query17	914	692	544	544
query18	2439	469	342	342
query19	209	183	145	145
query20	103	81	78	78
query21	229	132	113	113
query22	13027	13055	12850	12850
query23	13914	12985	12276	12276
query23_1	12474	12529	12439	12439
query24	7176	1182	668	668
query24_1	692	712	734	712
query25	572	431	373	373
query26	1273	310	164	164
query27	2713	512	338	338
query28	4553	1965	1951	1951
query29	1648	738	523	523
query30	301	222	185	185
query31	895	753	635	635
query32	146	102	95	95
query33	523	318	254	254
query34	1174	1081	595	595
query35	713	744	642	642
query36	782	766	718	718
query37	141	114	90	90
query38	1826	1760	1677	1677
query39	672	698	655	655
query39_1	646	648	643	643
query40	225	120	103	103
query41	70	68	69	68
query42	96	95	92	92
query43	333	341	293	293
query44	1353	694	708	694
query45	188	179	162	162
query46	1112	1174	716	716
query47	1494	1495	1488	1488
query48	422	422	292	292
query49	577	400	284	284
query50	916	351	244	244
query51	10580	10534	10221	10221
query52	88	91	73	73
query53	245	248	181	181
query54	241	193	200	193
query55	87	72	66	66
query56	230	222	213	213
query57	1505	1411	1355	1355
query58	277	256	253	253
query59	1983	2051	1856	1856
query60	289	238	231	231
query61	146	147	141	141
query62	396	322	269	269
query63	224	166	176	166
query64	2822	982	835	835
query65	3464	3393	3432	3393
query66	1800	417	299	299
query67	19790	20029	20006	20006
query68	3279	1565	880	880
query69	470	302	255	255
query70	929	833	833	833
query71	305	240	214	214
query72	2616	2602	2229	2229
query73	827	781	428	428
query74	4617	4472	4281	4281
query75	2286	2279	1908	1908
query76	2297	1094	721	721
query77	352	389	293	293
query78	9016	8987	8471	8471
query79	1348	1170	752	752
query80	580	461	364	364
query81	540	319	283	283
query82	627	163	124	124
query83	316	221	195	195
query84	315	143	121	121
query85	843	486	381	381
query86	329	248	235	235
query87	1998	1972	1851	1851
query88	3604	2720	2709	2709
query89	366	290	247	247
query90	1917	175	181	175
query91	182	157	127	127
query92	102	89	88	88
query93	1472	1492	812	812
query94	512	332	313	313
query95	635	454	329	329
query96	1122	804	333	333
query97	2445	2408	2301	2301
query98	162	148	142	142
query99	727	727	616	616
Total cold run time: 235616 ms
Total hot run time: 152045 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.05	0.05
query3	0.26	0.14	0.14
query4	1.61	0.14	0.14
query5	0.24	0.23	0.23
query6	1.15	0.93	0.93
query7	0.04	0.01	0.00
query8	0.06	0.04	0.04
query9	0.39	0.34	0.34
query10	0.54	0.53	0.57
query11	0.19	0.14	0.14
query12	0.18	0.15	0.14
query13	0.46	0.47	0.46
query14	0.95	0.94	0.94
query15	0.60	0.58	0.58
query16	0.30	0.32	0.32
query17	1.14	1.06	1.12
query18	0.22	0.20	0.20
query19	2.07	1.92	1.85
query20	0.03	0.01	0.01
query21	15.49	0.23	0.14
query22	4.87	0.06	0.05
query23	16.14	0.32	0.11
query24	2.93	0.44	0.32
query25	0.12	0.04	0.05
query26	0.73	0.20	0.14
query27	0.05	0.04	0.03
query28	3.52	0.77	0.34
query29	12.48	4.04	3.25
query30	0.29	0.17	0.15
query31	2.78	0.57	0.31
query32	3.25	0.59	0.49
query33	3.25	3.21	3.14
query34	15.38	3.94	3.29
query35	3.24	3.26	3.25
query36	0.56	0.45	0.43
query37	0.08	0.06	0.06
query38	0.04	0.04	0.03
query39	0.03	0.02	0.02
query40	0.17	0.14	0.15
query41	0.08	0.03	0.02
query42	0.04	0.02	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.1 s
Total hot run time: 23.92 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 70.39% (233/331) 🎉
Increment coverage report
Complete coverage report

@foxtail463
foxtail463 force-pushed the improvement/selected-partition-row-count branch from 2f5157a to 38cb694 Compare October 2, 2026 11:02
@foxtail463

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17679	3896	3905	3896
q2	2203	414	308	308
q3	10012	1386	793	793
q4	4677	475	349	349
q5	7509	831	554	554
q6	171	165	135	135
q7	735	779	600	600
q8	9302	1557	1551	1551
q9	5617	4215	4181	4181
q10	6824	1332	1012	1012
q11	430	270	239	239
q12	647	400	298	298
q13	18068	2595	1984	1984
q14	253	256	236	236
q15	q16	724	709	656	656
q17	1772	1173	1084	1084
q18	6596	5637	5556	5556
q19	1223	1286	1087	1087
q20	471	386	256	256
q21	5509	3311	2893	2893
q22	437	368	303	303
Total cold run time: 100859 ms
Total hot run time: 27971 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4603	4466	4480	4466
q2	708	563	544	544
q3	4756	5435	4630	4630
q4	2234	2309	1470	1470
q5	4596	4389	4492	4389
q6	236	171	128	128
q7	1819	1680	1490	1490
q8	2337	2095	2037	2037
q9	7235	6899	6840	6840
q10	3618	3550	3072	3072
q11	528	371	346	346
q12	714	705	509	509
q13	2273	2598	1995	1995
q14	267	277	257	257
q15	q16	660	691	604	604
q17	7328	6742	6650	6650
q18	11871	11062	11689	11062
q19	1141	1058	1018	1018
q20	2216	2185	1905	1905
q21	5012	4092	4266	4092
q22	520	452	388	388
Total cold run time: 64672 ms
Total hot run time: 57892 ms

@hello-stephen

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

query5	4303	600	475	475
query6	426	212	206	206
query7	4814	540	282	282
query8	319	191	174	174
query9	8806	3965	3957	3957
query10	493	317	261	261
query11	5922	3564	3244	3244
query12	165	92	87	87
query13	1260	612	423	423
query14	6507	4505	4223	4223
query14_1	3966	3953	3952	3952
query15	205	200	182	182
query16	1001	438	406	406
query17	898	637	522	522
query18	2462	448	329	329
query19	223	173	138	138
query20	80	77	77	77
query21	222	129	112	112
query22	12976	13069	12821	12821
query23	13963	13020	12486	12486
query23_1	12633	12609	12491	12491
query24	7196	1065	615	615
query24_1	731	680	669	669
query25	527	409	345	345
query26	1261	303	164	164
query27	2710	534	328	328
query28	4536	1952	1947	1947
query29	1583	686	510	510
query30	299	221	182	182
query31	877	738	637	637
query32	141	98	96	96
query33	526	310	250	250
query34	1175	1077	613	613
query35	729	753	628	628
query36	800	792	736	736
query37	142	106	96	96
query38	1836	1779	1695	1695
query39	699	696	675	675
query39_1	654	680	636	636
query40	223	127	101	101
query41	85	71	86	71
query42	96	91	91	91
query43	336	347	294	294
query44	1351	707	706	706
query45	182	178	166	166
query46	1066	1153	724	724
query47	1519	1514	1440	1440
query48	397	412	302	302
query49	599	407	298	298
query50	931	344	273	273
query51	10279	10248	10450	10248
query52	91	91	79	79
query53	255	255	189	189
query54	283	220	210	210
query55	79	76	70	70
query56	233	240	215	215
query57	1514	1500	1329	1329
query58	298	272	265	265
query59	1983	2044	1880	1880
query60	286	254	226	226
query61	166	171	168	168
query62	400	324	269	269
query63	216	182	179	179
query64	2930	1147	825	825
query65	3502	3433	3415	3415
query66	1796	425	301	301
query67	20235	20052	19958	19958
query68	3247	1549	911	911
query69	411	304	270	270
query70	907	788	801	788
query71	292	233	209	209
query72	2662	2502	2180	2180
query73	840	728	427	427
query74	4652	4491	4290	4290
query75	2302	2271	1932	1932
query76	2316	1097	761	761
query77	360	391	290	290
query78	9020	9036	8440	8440
query79	1376	1191	758	758
query80	580	474	371	371
query81	552	324	278	278
query82	622	155	123	123
query83	308	224	192	192
query84	328	148	113	113
query85	855	460	387	387
query86	336	245	215	215
query87	1983	1970	1835	1835
query88	3611	2698	2725	2698
query89	369	285	244	244
query90	1910	180	173	173
query91	171	154	131	131
query92	106	89	92	89
query93	1464	1349	898	898
query94	527	336	305	305
query95	663	451	325	325
query96	1112	768	360	360
query97	2414	2448	2373	2373
query98	167	152	146	146
query99	720	734	636	636
Total cold run time: 236345 ms
Total hot run time: 152341 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.09	0.05	0.05
query3	0.26	0.14	0.13
query4	1.60	0.14	0.14
query5	0.25	0.22	0.22
query6	1.16	0.93	0.93
query7	0.04	0.01	0.01
query8	0.05	0.04	0.04
query9	0.38	0.33	0.34
query10	0.54	0.53	0.58
query11	0.20	0.15	0.14
query12	0.19	0.15	0.14
query13	0.46	0.47	0.46
query14	0.94	0.94	0.95
query15	0.60	0.58	0.57
query16	0.30	0.33	0.31
query17	1.08	1.06	1.07
query18	0.22	0.19	0.20
query19	2.02	1.89	1.93
query20	0.02	0.02	0.01
query21	15.49	0.19	0.13
query22	4.93	0.06	0.05
query23	16.14	0.30	0.12
query24	2.98	0.40	0.31
query25	0.11	0.05	0.03
query26	0.72	0.20	0.14
query27	0.04	0.04	0.03
query28	3.57	0.77	0.34
query29	12.48	4.13	3.26
query30	0.29	0.15	0.15
query31	2.77	0.55	0.30
query32	3.22	0.59	0.50
query33	3.23	3.26	3.15
query34	15.61	3.94	3.24
query35	3.26	3.20	3.19
query36	0.54	0.44	0.42
query37	0.09	0.07	0.06
query38	0.05	0.04	0.03
query39	0.04	0.03	0.03
query40	0.17	0.15	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.3 s
Total hot run time: 23.81 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 70.39% (233/331) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 75.53% (250/331) 🎉
Increment coverage report
Complete coverage report

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants