Skip to content

[fix](fe) Fix correlated outer column in QUALIFY being mis-handled after GROUP BY / over project - #67152

Draft
starocean999 wants to merge 1 commit into
apache:masterfrom
starocean999:master_0415
Draft

[fix](fe) Fix correlated outer column in QUALIFY being mis-handled after GROUP BY / over project#67152
starocean999 wants to merge 1 commit into
apache:masterfrom
starocean999:master_0415

Conversation

@starocean999

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:
When a correlated subquery uses QUALIFY and references an outer column inside the
QUALIFY clause, the Nereids analyzer mishandles that outer column in all four
FillUpQualifyMissingSlot plan shapes:

  1. Qualify(Aggregate) / Qualify(Having, Aggregate) (explicit GROUP BY):
    Under the default ONLY_FULL_GROUP_BY SQL mode, the outer column is treated as an
    inner non-grouped column and the query is rejected.

    Reproduction:

    SELECT o.k
    FROM (
      SELECT CAST(10 AS INT) AS k, CAST(1 AS INT) AS flag
      UNION ALL
      SELECT CAST(20 AS INT) AS k, CAST(0 AS INT) AS flag
    ) AS o
    WHERE EXISTS (
      SELECT i.k
      FROM (
        SELECT CAST(1 AS INT) AS k
        UNION ALL
        SELECT CAST(2 AS INT) AS k
      ) AS i
      GROUP BY i.k
      QUALIFY row_number() OVER (ORDER BY i.k) = 1
              AND o.flag = 1
    );

    Before the fix this fails with:
    error 1105: QUALIFY expression 'flag' must appear in the GROUP BY clause or be used in an aggregate function.
    After the fix it returns a single row 10.

  2. Qualify(Project) / Qualify(Having, Project) (no GROUP BY):
    The correlated outer column is incorrectly pushed into the inner project's
    output, which the inner query cannot produce. This later crashes in
    PushProjectIntoUnion with a NullPointerException when the project is pushed
    into a UNION. The same query shape (without GROUP BY) reproduces this NPE;
    after the fix it also returns 10.

Root cause:

  • BindExpression binds the outer column from the enclosing outer Scope and records
    it in the outer Scope's correlated slots.
  • In FillUpQualifyMissingSlot:
    • The FILL_UP_QUALIFY_AGGREGATE and FILL_UP_QUALIFY_HAVING_AGGREGATE rules built
      the Resolver with new Resolver(agg) WITHOUT the outer scope (unlike the
      HAVING/SORT missing-slot paths which pass ctx.cascadesContext.getOuterScope()).
      Without it, the Resolver cannot tell a correlated outer slot from an inner
      missing group-by column, so under ONLY_FULL_GROUP_BY it throws.
    • The FILL_UP_QUALIFY_PROJECT and FILL_UP_QUALIFY_HAVING_PROJECT rules collect
      missing slots in createPlan with filter(s -> !projectOutputSet.contains(s))
      which also does not exclude correlated outer slots (unlike
      FillUpMissingSlots.collectNotExistsSlotAndAggFunc), so the outer column gets
      added to the inner project output.

The fix passes the outer scope into all four rules (via thenApply(ctx -> ...)):

  • FILL_UP_QUALIFY_AGGREGATE / FILL_UP_QUALIFY_HAVING_AGGREGATE: the Resolver
    now receives ctx.cascadesContext.getOuterScope() and skips slots found in the
    outer scope's correlated slots, matching the normal missing-slot paths.
  • FILL_UP_QUALIFY_PROJECT / FILL_UP_QUALIFY_HAVING_PROJECT: createPlan now
    receives the outer scope and filters correlated slots out of the project's
    notExistedInProject (and the distinct-branch missingSlots), so outer columns
    are never pushed into the inner project's output.

None

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

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

@starocean999

Copy link
Copy Markdown
Contributor Author

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

Two blocking FE/Nereids correctness issues remain in correlated QUALIFY handling: a dual HAVING/QUALIFY correlation can leave one outer predicate stranded below the window project, and a SELECT alias can hide an outer producer so EXISTS is lowered as uncorrelated. Both end in invalid plans rather than the intended rows.

Critical checkpoint conclusions:

  • Goal and functional proof: direct outer-slot references in the aggregate, project, and HAVING-project shapes are addressed, but the implementation does not cover the two legal variants called out inline. The fourth Qualify(Having(Aggregate)) branch is not proven by the added tests.
  • Plan semantics and parallel paths: binding uses the correct shared outer Scope and ExprIds. Direct references, DISTINCT reconstruction, HAVING/project, UNION-backed inputs, EXISTS/IN differences, window-project barriers, and APPLY-to-join lowering were traced end to end; the two inline failures are the surviving gaps.
  • Change scope: the patch is small and focused. No concurrency, lifecycle, configuration, protocol/storage compatibility, persistence, transaction, data-write, or FE/BE variable-passing concerns apply.
  • Tests and expected results: the three success outputs are deterministic and coherent, and the ONLY_FULL_GROUP_BY negative is preserved. Missing regressions are the dual correlated HAVING+QUALIFY aggregate shape and the outer-slot SELECT-alias shape. Per the review-only runner instructions, no build or regression test was run; live Checkstyle, formatting, license, title, and secret checks are passing.
  • Performance and observability: the added analysis-time set membership is negligible; no new runtime observability is required.
  • User focus: no additional focus was supplied.

Please address both inline blockers and add end-to-end regressions before merge.

logicalQualify(logicalHaving(aggregate())).then(qualify -> {
logicalQualify(logicalHaving(aggregate())).thenApply(ctx -> {
LogicalQualify<LogicalHaving<Aggregate<Plan>>> qualify = ctx.root;
checkWindow(qualify);

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.

[P1] Preserve both correlated filters across the window project

The new outer-scope resolver makes this branch accept a correlated QUALIFY, but the legal case with a separately correlated HAVING still fails. For EXISTS (SELECT i.k FROM i GROUP BY i.k HAVING o.h=1 QUALIFY row_number() OVER (ORDER BY i.k)=1 AND o.q=1), normalization produces this reduced tree:

Filter[QUALIFY o.q]
  Project[window]
    Filter[HAVING o.h]
      Aggregate[i.k]

Subquery unnesting runs before window extraction, and filter pushdown refuses a project containing a window expression. UnCorrelatedApplyFilter therefore records only o.q in the APPLY; ExistsApplyToJoin converts with that one predicate while o.h remains in the right subtree, which final slot validation rejects. Please decorrelate/conjoin both predicates across the window project (or reject the unsupported shape during analysis) and add the missing Qualify(Having(Aggregate)) regression.

Optional<Scope> outerScope, PlanGenerator planGenerator) {
Set<Slot> projectOutputSet = project.getOutputSet();
List<NamedExpression> newOutputSlots = Lists.newArrayList();
Set<Expression> newConjuncts = new LinkedHashSet<>();

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.

[P1] Resolve correlated producers hidden by SELECT aliases

This check misses an outer dependency hidden behind a project alias. For EXISTS (SELECT i.k, o.flag AS f, row_number() OVER (ORDER BY i.k) AS rn FROM i QUALIFY rn=1 AND f=1), QUALIFY is bound to project-local f/rn, so both inputs are already in projectOutputSet and createPlan returns without exposing producer o.flag. Because the project contains a window expression, filter pushdown cannot rewrite f back to its producer before APPLY decorrelation. The filter therefore does not intersect correlation slot o.flag, and EXISTS takes the uncorrelated path although the right project still reads the outer slot; final validation rejects that plan. Please preserve or resolve alias-producer dependencies for correlation extraction and cover this alias form with a regression.

@starocean999

Copy link
Copy Markdown
Contributor Author

/review

@starocean999

Copy link
Copy Markdown
Contributor Author

run buildall

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

Capped/incomplete after the mandatory three review rounds: this patch addresses the two existing correlated-QUALIFY threads, but ten additional correctness failures remain, consolidated into seven inline comments. The final round still produced a new accepted nested-IN ownership issue, so this review cannot claim convergence. The two earlier live P1 threads remain applicable and are not duplicated here.

Critical checkpoint conclusions:

  • Goal and proof: direct outer-slot cases improve, but grouped aliases, HAVING/window ordering, DISTINCT, computed producers, IN callers, and an earlier UNION path are not handled end to end. The added tests therefore do not prove the stated goal.
  • Scope and focus: the source change is small and focused, and no extra user focus was supplied; the semantic blast radius is nevertheless broad because the helper is shared by all four QUALIFY shapes and multiple Apply callers.
  • Concurrency: these are single-threaded analyzer/rewrite rules; no shared-state or locking concern applies.
  • Lifecycle: no resource or non-intuitive object lifecycle is introduced.
  • Configuration: no configuration item is added or changed.
  • Compatibility: no storage, protocol, symbol, rolling-upgrade, or FE/BE compatibility surface changes.
  • Parallel paths: the earlier PushProjectThroughUnion path bypasses the new late guard, and EXISTS, scalar, IN/NOT IN, and mark callers have different output-ownership contracts. These paths were traced through Apply-to-Join and final validation.
  • Conditional checks and error behavior: getInputSlots() containment is not sufficient proof that a HAVING predicate or alias producer can cross a window/subquery boundary; several cases change rows/errors or create dangling slots.
  • Test coverage: the JUnit tests stop after selected rewrites rather than final executable-plan validation. Regressions omit the grouped-alias, DISTINCT dual-correlation, HAVING phase, window/subquery producer, IN/mark, nested-IN, and width-matched UNION cases.
  • Test results: the committed expected outputs and expected-error form are coherent. Per the review-only prompt, no build or test was run locally.
  • Observability: no new runtime observability is needed for these planner-only changes.
  • Transactions, persistence, and data writes: not involved.
  • FE/BE variables: none are added or transmitted.
  • Performance: the new analysis-time set scans are small; no material performance issue was found.
  • Other current state: live head/base still match the authoritative bundle. Checkstyle, formatting, compile, BE UT, Cloud UT, and coverage are passing; cloud_p0 is currently failing and several regression/FE-UT/performance jobs remain pending, without enough evidence here to attribute that failure to this patch.

Please address the existing threads and all inline blockers, add full-pipeline regressions, and rerun review from a fresh authoritative bundle.

Aggregate<Plan> agg = qualify.child();
Resolver resolver = new Resolver(agg);
Resolver resolver = new Resolver(agg, ctx.cascadesContext.getOuterScope());
qualify.getConjuncts().forEach(expr -> resolver.resolve(expr, ResolvePlanType.QUALIFY));

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.

[P1] Resolve grouped output aliases to their outer producer

Passing outerScope to Resolver does not expose an outer dependency hidden by an aggregate-output alias. A reduced legal EXISTS subquery is:

Qualify[f = 1, rn = 1]
  Aggregate[groupBy=i.k; output=i.k, o.flag AS f, window AS rn]
    Scan(i)

Resolver.lookUp(f) finds the local output slot and records only f -> f; it adds no aggregate output and this rule returns unchanged. NormalizeAggregate later encounters o.flag in the output project without a child/group producer, so analysis/final slot validation fails. The added tests cover a direct outer slot with GROUP BY and an alias without GROUP BY, but not this cross-product. Please resolve a safe outer-only aggregate-output alias to its producer while preserving valid aggregate outputs, or reject this shape explicitly, and add a complete-pipeline grouped-alias regression.

if (inputSlots.isEmpty()) {
newHavingConjuncts.add(conjunct);
} else if (correlatedSlots.containsAll(inputSlots)) {
// the predicate only depends on the outer row, so it can safely be

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.

[P1] Do not infer HAVING/window commutativity from visible input slots

This containment check is not proof that a conjunct is constant over aggregate rows or safe to move across window evaluation. For example:

Qualify[rn = 1]
  Project[rn := row_number(order by i.k desc)]
    Having[count(*) = o.h]
      Aggregate[groupBy=i.k, count(*)]

count(*) = o.h reports only {o.h} as input slots, so the patch ranks every group before applying the predicate. With o.h=1, a one-row k=1 group and a two-row k=2 group, correct HAVING-first execution keeps k=1 and numbers it 1; the rewrite numbers k=2 first and returns no row. SubqueryExpr similarly hides a current-group correlation from getInputSlots(), and even a pure false outer predicate may be required to suppress an error-producing window key. Preserve HAVING below the window while making it decorrelatable, or conservatively reject shapes whose complete dependencies, determinism, and evaluation domain are not proven; add aggregate, nested-subquery, and error-gating regressions.

.flatMap(Set::stream)
.filter(s -> !projects.contains(s))
.filter(s -> !(outerScope.isPresent()
&& outerScope.get().getCorrelatedSlots().contains(s)))

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.

[P1] Keep both DISTINCT correlations reachable by the enclosing Apply

For a DISTINCT subquery with separately correlated HAVING and QUALIFY predicates, this branch builds the reduced tree:

Having[o.h]
  ProjectDistinct[i.k]
    Qualify[o.flag, rn]
      Project[i.k, rn := window]
        Scan(i)

Distinct conversion plus NormalizeAggregate inserts a Project -> Aggregate barrier between the two filters. UnCorrelatedApplyFilter first records o.h; the Apply's alreadyExecutedEliminateFilter fence then prevents pulling through the normalization project, and no aggregate-filter rule reaches the lower o.flag. Apply-to-Join therefore uses only o.h, leaving o.flag dangling in the right subtree. This is the DISTINCT/project parallel shape, not the existing Qualify(Having(Aggregate)) thread. Keep the correlated predicates on the same decorrelatable side of the distinct/window barriers, or reject the shape, and add the missing full-pipeline regression.

Expression producer = entry.getValue();
if (!producer.getInputSlots().isEmpty()
&& correlatedSlots.containsAll(producer.getInputSlots())) {
correlatedAliasToProducer.put(entry.getKey(), producer);

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.

[P1] Exclude window producers from this alias replacement cycle

A project alias can itself be a window over only outer slots:

Qualify[rn = 1]
  Project[row_number() over(order by o.flag) AS rn]
    Scan(i)

The map replaces rn with the window expression, then visitWindow immediately creates a fresh alias w1. The generated child is another Qualify(Project) whose w1 maps to the same window; the top-down analysis job revisits it, creates w2, and repeats without a fixed point before normalization or Apply unnesting. Restrict this repair to a producer class that cannot re-enter window extraction (or make the transformation explicitly idempotent), and add a full analyzer regression with a window partition/order key that is entirely correlated.

if (!producer.getInputSlots().isEmpty()
&& correlatedSlots.containsAll(producer.getInputSlots())) {
correlatedAliasToProducer.put(entry.getKey(), producer);
}

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.

[P1] Do not copy a producer subquery into both plan nodes

A producer such as o.flag + (SELECT max(j.k) FROM j) has visible input slots {o.flag}, so it enters this map even though it also contains a SubqueryExpr. Replacement leaves the same subquery in the lower project and copied upper QUALIFY expression:

Qualify[o.flag + scalarSubquery > 0]
  Project[o.flag + scalarSubquery AS f, window AS rn]

Bottom-up SubqueryToApply unnests the lower occurrence and marks that subquery analyzed. The upper occurrence is then replaced with the same output slot, but creation of its Apply is skipped by the global analyzed-expression fence; the intervening project does not output that slot, so final validation rejects the filter. Exclude producers containing SubqueryExpr from this substitution or materialize/unnest the producer exactly once at a shared level, with scalar and EXISTS producer regressions through CheckAfterRewrite.

boolean conjunctsRewritten = false;
if (!correlatedAliasToProducer.isEmpty()) {
Set<Expression> rewrittenConjuncts = ExpressionUtils.replace(conjuncts, correlatedAliasToProducer);
conjunctsRewritten = !rewrittenConjuncts.equals(conjuncts);

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.

[P1] Preserve slot ownership when replacement crosses IN boundaries

Replacing only the QUALIFY reference does not make the producer legal for every Apply caller. Two reduced failures remain:

Apply[IN, corr=o.flag]
  Scan(o)
  Project[o.flag AS f] -> Filter[o.flag=1, window]

Apply[EXISTS, corr=o.flag]
  Scan(o)
  Apply[IN, compare=o.flag](Project[f, window](Scan(i)), Scan(j))

In the first, IN/NOT IN must retain f as its build value; the IN-specific Project(Filter) fence preserves the right project, and InApplyToJoin leaves it consuming the left-only o.flag. In the second, ExpressionUtils.replace descends into InSubquery.child(), then SubqueryToApply removes that filter and stores o.flag only in the nested IN Apply's compareExpr; InApplyToJoin emits a nested join condition whose slot is produced by neither child. Both fail final slot validation (mark/OR has the same ownership issue). Reject unsupported outer-dependent IN outputs/nested compares, or materialize/pass the value at the correct Apply level, and add IN, NOT IN, nested-IN, and mark regressions.

// union, so pushing the project into the union would leave a dangling slot reference.
for (NamedExpression ne : project.getProjects()) {
if (!union.getOutputSet().containsAll(ne.getInputSlots())) {
return false;

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.

[P1] Enforce this ownership invariant in the earlier UNION rewrite

This late guard is bypassed by PushProjectThroughUnion, which runs before MergeOneRowRelationIntoUnion and this rule in both rewrite pipelines. For a width-matched project over a constant UNION ALL:

Project[i.k, o.flag AS f]
  UnionAll[OneRow(...), OneRow(...)]

PushProjectThroughUnion.canPushProject admits the project from width and bare/cast-slot shape alone; its replacement leaves o.flag unmapped in each one-row child. ProjectProcessor merges those projects and MergeOneRowRelationIntoUnion converts them to arity-zero constant rows, so this new check never executes and final validation sees a dangling outer slot. Apply the same child-output containment invariant before PushProjectThroughUnion rewrites the children (including the CTE registration), and add an end-to-end constant-UNION regression whose normalized project width matches the UNION width.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17549	3053	3039	3039
q2	2114	255	232	232
q3	10243	871	526	526
q4	4668	246	199	199
q5	7685	581	386	386
q6	139	115	94	94
q7	527	519	392	392
q8	9233	871	895	871
q9	3498	2438	2427	2427
q10	6527	853	700	700
q11	392	198	181	181
q12	618	259	196	196
q13	18158	1550	1168	1168
q14	160	152	142	142
q15	q16	432	395	370	370
q17	1355	943	821	821
q18	3071	2228	2231	2228
q19	1119	955	765	765
q20	373	286	203	203
q21	5245	1678	1906	1678
q22	323	274	233	233
Total cold run time: 93429 ms
Total hot run time: 16851 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3465	3368	3350	3350
q2	521	400	378	378
q3	2260	2385	2168	2168
q4	1196	1156	890	890
q5	2208	2122	2131	2122
q6	168	125	89	89
q7	1051	956	901	901
q8	1628	1448	1437	1437
q9	3166	3121	3122	3121
q10	1854	1819	1624	1624
q11	361	276	256	256
q12	459	431	342	342
q13	1493	1565	1162	1162
q14	168	170	171	170
q15	q16	393	399	366	366
q17	3601	3430	3266	3266
q18	4874	4446	4730	4446
q19	1516	901	860	860
q20	986	970	846	846
q21	3768	3049	3249	3049
q22	404	347	327	327
Total cold run time: 35540 ms
Total hot run time: 31170 ms

@hello-stephen

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

query5	4270	438	339	339
query6	384	135	124	124
query7	4929	421	236	236
query8	299	127	120	120
query9	8674	2907	2954	2907
query10	378	215	190	190
query11	5370	1025	910	910
query12	122	70	70	70
query13	1175	437	338	338
query14	6113	2229	2110	2110
query14_1	2008	1995	1981	1981
query15	180	115	111	111
query16	929	380	391	380
query17	812	454	373	373
query18	2328	330	237	237
query19	160	140	114	114
query20	78	70	73	70
query21	201	104	93	93
query22	5447	5298	5534	5298
query23	6651	6217	6022	6022
query23_1	5974	6121	6064	6064
query24	7296	1101	783	783
query24_1	783	784	781	781
query25	407	287	231	231
query26	1236	251	127	127
query27	2775	416	256	256
query28	4697	1484	1487	1484
query29	953	443	343	343
query30	250	157	124	124
query31	820	414	326	326
query32	133	77	69	69
query33	444	210	165	165
query34	987	867	497	497
query35	411	400	332	332
query36	564	579	551	551
query37	120	79	69	69
query38	1001	855	820	820
query39	505	475	488	475
query39_1	496	450	474	450
query40	200	89	75	75
query41	55	55	52	52
query42	74	79	71	71
query43	242	246	212	212
query44	1019	547	555	547
query45	113	107	100	100
query46	778	827	515	515
query47	780	770	712	712
query48	303	332	221	221
query49	548	235	192	192
query50	766	255	195	195
query51	8308	8258	8218	8218
query52	76	71	69	69
query53	200	207	154	154
query54	244	282	179	179
query55	78	65	57	57
query56	219	180	182	180
query57	688	676	663	663
query58	222	163	162	162
query59	1209	1229	1100	1100
query60	279	181	197	181
query61	118	130	128	128
query62	353	210	179	179
query63	171	145	142	142
query64	2763	683	585	585
query65	1610	1655	1612	1612
query66	1837	272	216	216
query67	10141	9634	9777	9634
query68	2764	1117	751	751
query69	357	222	189	189
query70	675	611	594	594
query71	254	176	171	171
query72	2328	1747	1618	1618
query73	666	590	339	339
query74	1587	1229	1149	1149
query75	1174	1101	971	971
query76	2293	748	568	568
query77	257	274	208	208
query78	4097	3713	3241	3241
query79	2414	822	579	579
query80	1615	340	273	273
query81	489	158	132	132
query82	622	139	94	94
query83	307	214	192	192
query84	291	108	92	92
query85	797	351	299	299
query86	386	174	174	174
query87	1000	967	903	903
query88	2807	2124	2105	2105
query89	285	197	170	170
query90	1949	133	128	128
query91	132	123	108	108
query92	84	70	70	70
query93	1469	1152	716	716
query94	656	264	226	226
query95	536	251	307	251
query96	812	584	263	263
query97	1070	1073	1011	1011
query98	148	134	131	131
query99	420	346	306	306
Total cold run time: 177926 ms
Total hot run time: 82544 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.07	0.04	0.03
query3	0.25	0.12	0.11
query4	1.60	0.10	0.10
query5	0.18	0.16	0.15
query6	1.26	0.70	0.66
query7	0.03	0.00	0.00
query8	0.05	0.03	0.04
query9	0.27	0.22	0.21
query10	0.34	0.34	0.34
query11	0.17	0.11	0.12
query12	0.14	0.12	0.12
query13	0.31	0.31	0.31
query14	0.46	0.45	0.46
query15	0.36	0.37	0.35
query16	0.23	0.24	0.22
query17	0.71	0.74	0.70
query18	0.18	0.17	0.17
query19	1.15	1.21	1.08
query20	0.02	0.01	0.01
query21	15.46	0.17	0.12
query22	5.05	0.04	0.05
query23	16.23	0.26	0.10
query24	3.00	0.31	0.27
query25	0.10	0.04	0.04
query26	0.84	0.18	0.12
query27	0.04	0.04	0.02
query28	3.67	0.52	0.29
query29	12.73	3.13	2.54
query30	0.25	0.12	0.12
query31	2.75	0.37	0.17
query32	3.53	0.31	0.23
query33	1.36	1.42	1.55
query34	15.36	2.23	1.77
query35	1.75	1.70	1.73
query36	0.46	0.29	0.29
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.03	0.02
query40	0.12	0.07	0.08
query41	0.07	0.03	0.02
query42	0.04	0.02	0.02
query43	0.04	0.03	0.03
Total cold run time: 90.78 s
Total hot run time: 14.62 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.

2 participants