Skip to content

Implement intermediate result blocked approach to aggregation memory management #15591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 43 commits into
base: main
Choose a base branch
from

Conversation

Rachelint
Copy link
Contributor

@Rachelint Rachelint commented Apr 5, 2025

Which issue does this PR close?

Rationale for this change

As mentioned in #7065 , we use a single Vec to manage aggregation intermediate results both in GroupAccumulator and GroupValues.

It is simple but not efficient enough in high-cardinality aggregation, because when Vec is not large enough, we need to allocate a new Vec and copy all data from the old one.

  • Copying a large amount of data(due to high-cardinality) is obviously expansive
  • And it is also not friendly to cpu (will refresh cache and tlb)

So this pr introduces a blocked approach to manage the aggregation intermediate results. We will never resize the Vec in the approach, and instead we split the data to blocks, when the capacity is not enough, we just allocate a new block. Detail can see #7065

What changes are included in this PR?

  • Implement the sketch for blocked approach
  • Implement blocked groups supporting PrimitiveGroupsAccumulator and GroupValuesPrimitive as the example

Are these changes tested?

Test by exist tests. And new unit tests, new fuzzy tests.

Are there any user-facing changes?

Two functions are added to GroupValues and GroupAccumulator trait.

But as you can see, there are default implementations for them, and users can choose to really support the blocked approach when wanting a better performance for their udafs.

    /// Returns `true` if this accumulator supports blocked groups.
    fn supports_blocked_groups(&self) -> bool {
        false
    }

    /// Alter the block size in the accumulator
    ///
    /// If the target block size is `None`, it will use a single big
    /// block(can think it a `Vec`) to manage the state.
    ///
    /// If the target block size` is `Some(blk_size)`, it will try to
    /// set the block size to `blk_size`, and the try will only success
    /// when the accumulator has supported blocked mode.
    ///
    /// NOTICE: After altering block size, all data in previous will be cleared.
    ///
    fn alter_block_size(&mut self, block_size: Option<usize>) -> Result<()> {
        if block_size.is_some() {
            return Err(DataFusionError::NotImplemented(
                "this accumulator doesn't support blocked mode yet".to_string(),
            ));
        }

        Ok(())
    }

@Rachelint Rachelint changed the title Impl Intermeidate result blocked approach framework Impl intermeidate result blocked approach framework Apr 5, 2025
@Rachelint Rachelint changed the title Impl intermeidate result blocked approach framework Impl intermeidate result blocked approach sketch Apr 5, 2025
@github-actions github-actions bot added the logical-expr Logical plan and expressions label Apr 5, 2025
@Dandandan
Copy link
Contributor

Hi @Rachelint I think I have a alternative proposal that seems relatively easy to implement.
I'll share it with you once I have some time to validate the design (probably this evening).

@Rachelint
Copy link
Contributor Author

Rachelint commented Apr 8, 2025

Hi @Rachelint I think I have a alternative proposal that seems relatively easy to implement. I'll share it with you once I have some time to validate the design (probably this evening).

Really thanks. This design in pr indeed still introduces quite a few code changes...

I tried to not modify anythings about GroupAccumulator firstly:

  • Only implement the blocked logic in GroupValues
  • Then we reorder the input batch according to their block indices got from GroupValues
  • Apply input batch to related GroupAccumulator using slice
  • And when we found the new block is needed, create a new GroupAccumulator (one block one GroupAccumulator)

But I found this way will introduce too many extra cost...

Maybe we place the block indices into values in merge/update_batch as a Array?

@Rachelint Rachelint force-pushed the intermeidate-result-blocked-approach branch 2 times, most recently from cc37eba to f690940 Compare April 9, 2025 14:37
@github-actions github-actions bot added the functions Changes to functions implementation label Apr 10, 2025
@Rachelint Rachelint force-pushed the intermeidate-result-blocked-approach branch from 95c6a36 to a4c6f42 Compare April 10, 2025 11:10
@github-actions github-actions bot added the physical-expr Changes to the physical-expr crates label Apr 10, 2025
@Rachelint Rachelint force-pushed the intermeidate-result-blocked-approach branch 6 times, most recently from 2100a5b to 0ee951c Compare April 17, 2025 11:56
@Rachelint
Copy link
Contributor Author

Rachelint commented Apr 17, 2025

Has finished development(and test) of all needed common structs!
Rest four things for this one:

  • Support blocked related logic in GroupedHashAggregateStream(we can copy it from Sketch for aggregation intermediate results blocked management #11943 )
  • Logic about deciding when we should enable this optimization
  • Example blocked version for GroupAccumulator and GroupValues
  • Unit test for blocked GroupValuesPrimitive, it is a bit complex
  • Fuzzy tests
  • Chore: fix docs, fix clippy, add more comments...

@Rachelint Rachelint force-pushed the intermeidate-result-blocked-approach branch 2 times, most recently from c51d409 to 2863809 Compare April 20, 2025 14:46
@github-actions github-actions bot added execution Related to the execution crate common Related to common crate sqllogictest SQL Logic Tests (.slt) labels Apr 21, 2025
@Rachelint
Copy link
Contributor Author

It is very close, just need to add more tests!

@Rachelint Rachelint force-pushed the intermeidate-result-blocked-approach branch 3 times, most recently from 31d660d to 2b8dd1e Compare April 22, 2025 18:52
@alamb alamb changed the title Implement intermeidate result blocked approach sketch Implement intermediate result blocked approach sketch May 2, 2025
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

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

👏 👏 -- this PR is amazing @Rachelint -- it looks really nice and the code is very well structured and easy to read and understand (which is non trivial, given that this is some of the most complicated and performance sensitive parts of the code). I very much enjoyed reading this PR

I will run some benchmarks shortly but from my perspective if this shows a performance improvement we could merge this PR. I have a few suggestions, but I think they can all be done in a follow on PR

My largest concern with this PR is that it makes aggregation, one of the most complex parts of the code, even more complex as there is now another potential code path through all the aggregates

I think a new codepath is ok if it is temporary while we port over other GroupsAccumulators / GroupValues to use blocked management then we remove the non blocked version. However if there is some reason we can't port the other accumulators over to use blocked management I think we should reconsider.

I would be more than happy to help organize the effort (aka file tickets!) to port the remaining GroupsAccumulators over and remove the non blocked version

Now that I review the code, it seems like we have the same basic complexity creeping in via supports_convert_to_state 🤔 -- maybe we should also work on removing that (force all groups accumulators to implement convert_to_state) -- which would also likely improve performance -- I can work on filing tickets for that too

@@ -5,3 +5,4 @@ SELECT "SocialSourceNetworkID", "RegionID", COUNT(*), AVG("Age"), AVG("ParamPric
SELECT "ClientIP", "WatchID", COUNT(*) c, MIN("ResponseStartTiming") tmin, MEDIAN("ResponseStartTiming") tmed, MAX("ResponseStartTiming") tmax FROM hits WHERE "JavaEnable" = 0 GROUP BY "ClientIP", "WatchID" HAVING c > 1 ORDER BY tmed DESC LIMIT 10;
SELECT "ClientIP", "WatchID", COUNT(*) c, MIN("ResponseStartTiming") tmin, APPROX_PERCENTILE_CONT("ResponseStartTiming", 0.95) tp95, MAX("ResponseStartTiming") tmax FROM 'hits' WHERE "JavaEnable" = 0 GROUP BY "ClientIP", "WatchID" HAVING c > 1 ORDER BY tp95 DESC LIMIT 10;
SELECT COUNT(*) AS ShareCount FROM hits WHERE "IsMobile" = 1 AND "MobilePhoneModel" LIKE 'iPhone%' AND "SocialAction" = 'share' AND "SocialSourceNetworkID" IN (5, 12) AND "ClientTimeZone" BETWEEN -5 AND 5 AND regexp_match("Referer", '\/campaign\/(spring|summer)_promo') IS NOT NULL AND CASE WHEN split_part(split_part("URL", 'resolution=', 2), '&', 1) ~ '^\d+$' THEN split_part(split_part("URL", 'resolution=', 2), '&', 1)::INT ELSE 0 END > 1920 AND levenshtein(CAST("UTMSource" AS STRING), CAST("UTMCampaign" AS STRING)) < 3;
SELECT "WatchID", MIN("ResolutionWidth"), MAX("ResolutionWidth"), SUM("IsRefresh") FROM hits GROUP BY "WatchID" ORDER BY "WatchID" DESC LIMIT 10;
Copy link
Contributor

Choose a reason for hiding this comment

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

If we are going to add a new query to the extended benchmarks, can we please also document the query here?

https://github.com/apache/datafusion/tree/main/benchmarks/queries/clickbench#extended-queries

?

Copy link
Contributor Author

@Rachelint Rachelint May 3, 2025

Choose a reason for hiding this comment

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

Addressed with #15936

@@ -405,6 +405,18 @@ config_namespace! {
/// in joins can reduce memory usage when joining large
/// tables with a highly-selective join filter, but is also slightly slower.
pub enforce_batch_size_in_joins: bool, default = false

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you expect users will ever disable this feature? Or does this setting exist as an "escape" valve in case we hit a problem with the new behavior and want to go back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is just a way for going back + testing.

}

impl EmitTo {
/// Remove and return `needed values` from `values`.
pub fn take_needed<T>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you document what the is_blocked_groups parameter means too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed

/// set the block size to `blk_size`, and the try will only success
/// when the accumulator has supported blocked mode.
///
/// NOTICE: After altering block size, all data in previous will be cleared.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean that all existing accumulators will be cleared?

Copy link
Contributor Author

@Rachelint Rachelint May 3, 2025

Choose a reason for hiding this comment

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

Yes, it will be usually used in load back + merge step in spilling:

  • Emit the rest blocks at first
  • Clear all stale data, and switch to flat mode and perform sorted aggregation

@@ -51,6 +51,7 @@ datafusion-common = { workspace = true, default-features = true }
datafusion-common-runtime = { workspace = true, default-features = true }
datafusion-execution = { workspace = true }
datafusion-expr = { workspace = true }
datafusion-functions-aggregate-common = { workspace = true }
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this new dependency is ok as it doesn't use any specific aggregate implementation which we are trying to avoid

/// `group values` will be stored in multiple `Vec`s, and each
/// `Vec` if of `blk_size` len, and we call it a `block`
///
block_size: Option<usize>,
Copy link
Contributor

Choose a reason for hiding this comment

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

See my comment above about making a Blocks struct which I think would avoid some non trivial duplication

@@ -982,6 +1099,9 @@ impl GroupedHashAggregateStream {
&& self.update_memory_reservation().is_err()
{
assert_ne!(self.mode, AggregateMode::Partial);
// TODO: support spilling when blocked group optimization is on
Copy link
Contributor

Choose a reason for hiding this comment

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

We may want to file a ticket to track this -- but I think in general figuring out how to handle spilling for hashing in a better way is worth considering so maybe this particular task would become irrelevant

}
}

pub(crate) trait Block {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be good to add some comments here describing what the trait is for

/// If `row_x group_index_x` is not filtered(`group_index_x` is seen)
/// `seen_values[group_index_x]` will be set to `true`.
///
/// For `set_bit(block_id, block_offset, value)`, `block_id` is unused,
Copy link
Contributor

Choose a reason for hiding this comment

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

Something I didn't see documented anywhere was what block_id and block_offset meant -- maybe we could add something on the HashAggregateStream 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed.
I add related comments in GroupsAccumulator::supports_blocked_groups and GroupValues::supports_blocked_groups, also link it in HashAggregateStream.

@alamb alamb changed the title Implement intermediate result blocked approach sketch Implement intermediate result blocked approach to aggregation memory management May 2, 2025
@alamb
Copy link
Contributor

alamb commented May 2, 2025

🤖 ./gh_compare_branch.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing intermeidate-result-blocked-approach (ff9c3ad) to 74dc419 diff
Benchmarks: clickbench_1 tpch_mem
Results will be posted here when complete

@alamb
Copy link
Contributor

alamb commented May 2, 2025

🤖: Benchmark completed

Details

Comparing HEAD and intermeidate-result-blocked-approach
--------------------
Benchmark clickbench_1.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0     │     0.57ms │                               0.55ms │     no change │
│ QQuery 1     │    73.94ms │                              75.00ms │     no change │
│ QQuery 2     │   113.27ms │                             118.51ms │     no change │
│ QQuery 3     │   126.34ms │                             126.51ms │     no change │
│ QQuery 4     │   754.71ms │                             789.90ms │     no change │
│ QQuery 5     │   834.40ms │                             836.35ms │     no change │
│ QQuery 6     │     0.70ms │                               0.62ms │ +1.13x faster │
│ QQuery 7     │    87.54ms │                              89.84ms │     no change │
│ QQuery 8     │   921.68ms │                             928.83ms │     no change │
│ QQuery 9     │  1217.57ms │                            1197.21ms │     no change │
│ QQuery 10    │   291.89ms │                             308.86ms │  1.06x slower │
│ QQuery 11    │   334.85ms │                             344.94ms │     no change │
│ QQuery 12    │   892.72ms │                             900.44ms │     no change │
│ QQuery 13    │  1317.81ms │                            1308.76ms │     no change │
│ QQuery 14    │   840.55ms │                             857.04ms │     no change │
│ QQuery 15    │  1039.30ms │                            1101.46ms │  1.06x slower │
│ QQuery 16    │  1749.21ms │                            1742.09ms │     no change │
│ QQuery 17    │  1583.83ms │                            1614.13ms │     no change │
│ QQuery 18    │  3067.32ms │                            3093.76ms │     no change │
│ QQuery 19    │   123.92ms │                             115.09ms │ +1.08x faster │
│ QQuery 20    │  1153.71ms │                            1169.49ms │     no change │
│ QQuery 21    │  1396.36ms │                            1397.95ms │     no change │
│ QQuery 22    │  2417.82ms │                            2395.93ms │     no change │
│ QQuery 23    │  8439.01ms │                            8627.38ms │     no change │
│ QQuery 24    │   502.46ms │                             491.22ms │     no change │
│ QQuery 25    │   427.03ms │                             433.83ms │     no change │
│ QQuery 26    │   558.27ms │                             575.80ms │     no change │
│ QQuery 27    │  1822.79ms │                            1834.22ms │     no change │
│ QQuery 28    │ 12992.87ms │                           12962.28ms │     no change │
│ QQuery 29    │   567.61ms │                             569.25ms │     no change │
│ QQuery 30    │   834.68ms │                             849.39ms │     no change │
│ QQuery 31    │   874.85ms │                             911.69ms │     no change │
│ QQuery 32    │  2620.91ms │                            2712.46ms │     no change │
│ QQuery 33    │  3374.68ms │                            3414.17ms │     no change │
│ QQuery 34    │  3508.23ms │                            3471.25ms │     no change │
│ QQuery 35    │  1299.74ms │                            1283.55ms │     no change │
│ QQuery 36    │   168.83ms │                             178.94ms │  1.06x slower │
│ QQuery 37    │   100.58ms │                             104.48ms │     no change │
│ QQuery 38    │   169.06ms │                             175.10ms │     no change │
│ QQuery 39    │   251.47ms │                             256.55ms │     no change │
│ QQuery 40    │    84.92ms │                              88.19ms │     no change │
│ QQuery 41    │    85.41ms │                              83.15ms │     no change │
│ QQuery 42    │    79.02ms │                              77.87ms │     no change │
└──────────────┴────────────┴──────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 59102.46ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 59614.05ms │
│ Average Time (HEAD)                                 │  1374.48ms │
│ Average Time (intermeidate-result-blocked-approach) │  1386.37ms │
│ Queries Faster                                      │          2 │
│ Queries Slower                                      │          3 │
│ Queries with No Change                              │         38 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark tpch_mem_sf1.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃     HEAD ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1     │ 123.82ms │                             124.51ms │     no change │
│ QQuery 2     │  23.48ms │                              23.82ms │     no change │
│ QQuery 3     │  35.83ms │                              34.47ms │     no change │
│ QQuery 4     │  21.19ms │                              21.19ms │     no change │
│ QQuery 5     │  55.49ms │                              55.51ms │     no change │
│ QQuery 6     │  12.07ms │                              12.25ms │     no change │
│ QQuery 7     │ 102.21ms │                             102.45ms │     no change │
│ QQuery 8     │  26.52ms │                              25.42ms │     no change │
│ QQuery 9     │  63.17ms │                              60.87ms │     no change │
│ QQuery 10    │  57.73ms │                              58.82ms │     no change │
│ QQuery 11    │  13.17ms │                              12.91ms │     no change │
│ QQuery 12    │  44.63ms │                              45.62ms │     no change │
│ QQuery 13    │  29.14ms │                              30.79ms │  1.06x slower │
│ QQuery 14    │   9.69ms │                               9.76ms │     no change │
│ QQuery 15    │  24.90ms │                              24.88ms │     no change │
│ QQuery 16    │  24.00ms │                              23.69ms │     no change │
│ QQuery 17    │  96.51ms │                              97.27ms │     no change │
│ QQuery 18    │ 241.93ms │                             232.20ms │     no change │
│ QQuery 19    │  27.85ms │                              28.84ms │     no change │
│ QQuery 20    │  39.30ms │                              38.43ms │     no change │
│ QQuery 21    │ 173.40ms │                             172.61ms │     no change │
│ QQuery 22    │  17.56ms │                              16.65ms │ +1.05x faster │
└──────────────┴──────────┴──────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 1263.57ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 1252.96ms │
│ Average Time (HEAD)                                 │   57.44ms │
│ Average Time (intermeidate-result-blocked-approach) │   56.95ms │
│ Queries Faster                                      │         1 │
│ Queries Slower                                      │         1 │
│ Queries with No Change                              │        20 │
└─────────────────────────────────────────────────────┴───────────┘

@jayzhan211
Copy link
Contributor

jayzhan211 commented May 3, 2025

how is the benchmark triggered and can we run clickbench extended too?

upd: I didn't find improvement for extended query locally

@alamb
Copy link
Contributor

alamb commented May 3, 2025

how is the benchmark triggered and can we run clickbench extended too?

I am using some scripts in https://github.com/alamb/datafusion-benchmarking on a gcp machine (I haven't figured out how we would do this for the community in general

I didn't run the extended tests because they ran into the following issue (which is how I found it initially)

Now that they are fixed I think I can run extended tests and will kick them off

@alamb
Copy link
Contributor

alamb commented May 3, 2025

🤖: Benchmark completed

(I am surprised this PR didn't yield better results, I am reruning now to see if the results are reproducable

@alamb
Copy link
Contributor

alamb commented May 3, 2025

🤖 ./gh_compare_branch.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing intermeidate-result-blocked-approach (ff9c3ad) to 74dc419 diff
Benchmarks: tpch_mem clickbench_partitioned clickbench_extended
Results will be posted here when complete

@Rachelint
Copy link
Contributor Author

🤖: Benchmark completed

(I am surprised this PR didn't yield better results, I am reruning now to see if the results are reproducable

I am back from holiday, and continue to work on this today.

Because for simplicity for the initial pr, I just:

  • Implement the blocked version GroupValuesPrimitive for GroupValues
  • and PrimitiveGroupsAccumulator for GroupAccumulator

And actually still don't have such a simple query can show the improvement now...

And for showing the improvement, I add an new query in clickbench/extended.sql:

SELECT "WatchID", MIN("ResolutionWidth"), MAX("ResolutionWidth"), SUM("IsRefresh") FROM hits GROUP BY "WatchID" ORDER BY "WatchID" DESC LIMIT 10;

@Rachelint
Copy link
Contributor Author

how is the benchmark triggered and can we run clickbench extended too?

upd: I didn't find improvement for extended query locally

Also for the new added one?

SELECT "WatchID", MIN("ResolutionWidth"), MAX("ResolutionWidth"), SUM("IsRefresh") FROM hits GROUP BY "WatchID" ORDER BY "WatchID" DESC LIMIT 10;

@alamb
Copy link
Contributor

alamb commented May 3, 2025

🤖: Benchmark completed

Details

Comparing HEAD and intermeidate-result-blocked-approach
--------------------
Benchmark clickbench_extended.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 0     │  1921.22ms │                            1898.23ms │    no change │
│ QQuery 1     │   657.26ms │                             694.92ms │ 1.06x slower │
│ QQuery 2     │  1398.94ms │                            1419.32ms │    no change │
│ QQuery 3     │   713.54ms │                             717.51ms │    no change │
│ QQuery 4     │  1498.02ms │                            1511.57ms │    no change │
│ QQuery 5     │ 15341.63ms │                           15578.65ms │    no change │
│ QQuery 6     │  2029.05ms │                            2049.81ms │    no change │
└──────────────┴────────────┴──────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 23559.67ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 23870.00ms │
│ Average Time (HEAD)                                 │  3365.67ms │
│ Average Time (intermeidate-result-blocked-approach) │  3410.00ms │
│ Queries Faster                                      │          0 │
│ Queries Slower                                      │          1 │
│ Queries with No Change                              │          6 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0     │     2.32ms │                               2.31ms │     no change │
│ QQuery 1     │    36.90ms │                              38.43ms │     no change │
│ QQuery 2     │    91.60ms │                              93.54ms │     no change │
│ QQuery 3     │   100.24ms │                              99.54ms │     no change │
│ QQuery 4     │   777.83ms │                             801.76ms │     no change │
│ QQuery 5     │   860.11ms │                             850.06ms │     no change │
│ QQuery 6     │     2.10ms │                               2.13ms │     no change │
│ QQuery 7     │    41.49ms │                              43.64ms │  1.05x slower │
│ QQuery 8     │   925.11ms │                             877.46ms │ +1.05x faster │
│ QQuery 9     │  1201.13ms │                            1193.97ms │     no change │
│ QQuery 10    │   262.49ms │                             270.08ms │     no change │
│ QQuery 11    │   302.47ms │                             313.89ms │     no change │
│ QQuery 12    │   902.20ms │                             956.22ms │  1.06x slower │
│ QQuery 13    │  1325.06ms │                            1388.51ms │     no change │
│ QQuery 14    │   826.08ms │                             851.33ms │     no change │
│ QQuery 15    │  1026.88ms │                            1061.12ms │     no change │
│ QQuery 16    │  1720.69ms │                            1731.12ms │     no change │
│ QQuery 17    │  1582.12ms │                            1599.34ms │     no change │
│ QQuery 18    │  3066.54ms │                            3254.59ms │  1.06x slower │
│ QQuery 19    │    84.76ms │                              82.92ms │     no change │
│ QQuery 20    │  1116.50ms │                            1178.43ms │  1.06x slower │
│ QQuery 21    │  1315.33ms │                            1318.33ms │     no change │
│ QQuery 22    │  2190.24ms │                            2170.50ms │     no change │
│ QQuery 23    │  8290.39ms │                            8370.27ms │     no change │
│ QQuery 24    │   470.87ms │                             486.49ms │     no change │
│ QQuery 25    │   388.04ms │                             399.37ms │     no change │
│ QQuery 26    │   527.09ms │                             542.36ms │     no change │
│ QQuery 27    │  1686.91ms │                            1727.53ms │     no change │
│ QQuery 28    │ 12444.07ms │                           12631.97ms │     no change │
│ QQuery 29    │   525.46ms │                             534.61ms │     no change │
│ QQuery 30    │   798.93ms │                             822.60ms │     no change │
│ QQuery 31    │   829.79ms │                             870.36ms │     no change │
│ QQuery 32    │  2594.87ms │                            2731.68ms │  1.05x slower │
│ QQuery 33    │  3320.81ms │                            3380.18ms │     no change │
│ QQuery 34    │  3357.44ms │                            3387.27ms │     no change │
│ QQuery 35    │  1290.00ms │                            1282.24ms │     no change │
│ QQuery 36    │   130.81ms │                             126.75ms │     no change │
│ QQuery 37    │    57.49ms │                              58.36ms │     no change │
│ QQuery 38    │   127.97ms │                             128.85ms │     no change │
│ QQuery 39    │   204.48ms │                             207.11ms │     no change │
│ QQuery 40    │    50.31ms │                              48.89ms │     no change │
│ QQuery 41    │    48.25ms │                              44.18ms │ +1.09x faster │
│ QQuery 42    │    39.38ms │                              38.45ms │     no change │
└──────────────┴────────────┴──────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 56943.53ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 57998.74ms │
│ Average Time (HEAD)                                 │  1324.27ms │
│ Average Time (intermeidate-result-blocked-approach) │  1348.81ms │
│ Queries Faster                                      │          2 │
│ Queries Slower                                      │          5 │
│ Queries with No Change                              │         36 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark tpch_mem_sf1.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃     HEAD ┃ intermeidate-result-blocked-approach ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 1     │ 124.78ms │                             130.74ms │    no change │
│ QQuery 2     │  24.32ms │                              23.65ms │    no change │
│ QQuery 3     │  35.37ms │                              35.46ms │    no change │
│ QQuery 4     │  20.87ms │                              20.87ms │    no change │
│ QQuery 5     │  54.85ms │                              57.66ms │ 1.05x slower │
│ QQuery 6     │  12.21ms │                              12.64ms │    no change │
│ QQuery 7     │  99.22ms │                             102.82ms │    no change │
│ QQuery 8     │  26.11ms │                              25.50ms │    no change │
│ QQuery 9     │  63.11ms │                              64.15ms │    no change │
│ QQuery 10    │  57.98ms │                              59.17ms │    no change │
│ QQuery 11    │  13.04ms │                              13.20ms │    no change │
│ QQuery 12    │  43.72ms │                              44.49ms │    no change │
│ QQuery 13    │  28.90ms │                              29.45ms │    no change │
│ QQuery 14    │   9.78ms │                              10.58ms │ 1.08x slower │
│ QQuery 15    │  26.05ms │                              25.35ms │    no change │
│ QQuery 16    │  23.45ms │                              23.66ms │    no change │
│ QQuery 17    │  95.93ms │                              97.78ms │    no change │
│ QQuery 18    │ 240.22ms │                             238.96ms │    no change │
│ QQuery 19    │  27.56ms │                              28.63ms │    no change │
│ QQuery 20    │  38.46ms │                              38.79ms │    no change │
│ QQuery 21    │ 173.00ms │                             168.56ms │    no change │
│ QQuery 22    │  18.15ms │                              17.81ms │    no change │
└──────────────┴──────────┴──────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 1257.09ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 1269.90ms │
│ Average Time (HEAD)                                 │   57.14ms │
│ Average Time (intermeidate-result-blocked-approach) │   57.72ms │
│ Queries Faster                                      │         0 │
│ Queries Slower                                      │         2 │
│ Queries with No Change                              │        20 │
└─────────────────────────────────────────────────────┴───────────┘

@Rachelint
Copy link
Contributor Author

Rachelint commented May 3, 2025

🤖: Benchmark completed
Details

Comparing HEAD and intermeidate-result-blocked-approach
--------------------
Benchmark clickbench_extended.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 0     │  1921.22ms │                            1898.23ms │    no change │
│ QQuery 1     │   657.26ms │                             694.92ms │ 1.06x slower │
│ QQuery 2     │  1398.94ms │                            1419.32ms │    no change │
│ QQuery 3     │   713.54ms │                             717.51ms │    no change │
│ QQuery 4     │  1498.02ms │                            1511.57ms │    no change │
│ QQuery 5     │ 15341.63ms │                           15578.65ms │    no change │
│ QQuery 6     │  2029.05ms │                            2049.81ms │    no change │
└──────────────┴────────────┴──────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 23559.67ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 23870.00ms │
│ Average Time (HEAD)                                 │  3365.67ms │
│ Average Time (intermeidate-result-blocked-approach) │  3410.00ms │
│ Queries Faster                                      │          0 │
│ Queries Slower                                      │          1 │
│ Queries with No Change                              │          6 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0     │     2.32ms │                               2.31ms │     no change │
│ QQuery 1     │    36.90ms │                              38.43ms │     no change │
│ QQuery 2     │    91.60ms │                              93.54ms │     no change │
│ QQuery 3     │   100.24ms │                              99.54ms │     no change │
│ QQuery 4     │   777.83ms │                             801.76ms │     no change │
│ QQuery 5     │   860.11ms │                             850.06ms │     no change │
│ QQuery 6     │     2.10ms │                               2.13ms │     no change │
│ QQuery 7     │    41.49ms │                              43.64ms │  1.05x slower │
│ QQuery 8     │   925.11ms │                             877.46ms │ +1.05x faster │
│ QQuery 9     │  1201.13ms │                            1193.97ms │     no change │
│ QQuery 10    │   262.49ms │                             270.08ms │     no change │
│ QQuery 11    │   302.47ms │                             313.89ms │     no change │
│ QQuery 12    │   902.20ms │                             956.22ms │  1.06x slower │
│ QQuery 13    │  1325.06ms │                            1388.51ms │     no change │
│ QQuery 14    │   826.08ms │                             851.33ms │     no change │
│ QQuery 15    │  1026.88ms │                            1061.12ms │     no change │
│ QQuery 16    │  1720.69ms │                            1731.12ms │     no change │
│ QQuery 17    │  1582.12ms │                            1599.34ms │     no change │
│ QQuery 18    │  3066.54ms │                            3254.59ms │  1.06x slower │
│ QQuery 19    │    84.76ms │                              82.92ms │     no change │
│ QQuery 20    │  1116.50ms │                            1178.43ms │  1.06x slower │
│ QQuery 21    │  1315.33ms │                            1318.33ms │     no change │
│ QQuery 22    │  2190.24ms │                            2170.50ms │     no change │
│ QQuery 23    │  8290.39ms │                            8370.27ms │     no change │
│ QQuery 24    │   470.87ms │                             486.49ms │     no change │
│ QQuery 25    │   388.04ms │                             399.37ms │     no change │
│ QQuery 26    │   527.09ms │                             542.36ms │     no change │
│ QQuery 27    │  1686.91ms │                            1727.53ms │     no change │
│ QQuery 28    │ 12444.07ms │                           12631.97ms │     no change │
│ QQuery 29    │   525.46ms │                             534.61ms │     no change │
│ QQuery 30    │   798.93ms │                             822.60ms │     no change │
│ QQuery 31    │   829.79ms │                             870.36ms │     no change │
│ QQuery 32    │  2594.87ms │                            2731.68ms │  1.05x slower │
│ QQuery 33    │  3320.81ms │                            3380.18ms │     no change │
│ QQuery 34    │  3357.44ms │                            3387.27ms │     no change │
│ QQuery 35    │  1290.00ms │                            1282.24ms │     no change │
│ QQuery 36    │   130.81ms │                             126.75ms │     no change │
│ QQuery 37    │    57.49ms │                              58.36ms │     no change │
│ QQuery 38    │   127.97ms │                             128.85ms │     no change │
│ QQuery 39    │   204.48ms │                             207.11ms │     no change │
│ QQuery 40    │    50.31ms │                              48.89ms │     no change │
│ QQuery 41    │    48.25ms │                              44.18ms │ +1.09x faster │
│ QQuery 42    │    39.38ms │                              38.45ms │     no change │
└──────────────┴────────────┴──────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 56943.53ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 57998.74ms │
│ Average Time (HEAD)                                 │  1324.27ms │
│ Average Time (intermeidate-result-blocked-approach) │  1348.81ms │
│ Queries Faster                                      │          2 │
│ Queries Slower                                      │          5 │
│ Queries with No Change                              │         36 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark tpch_mem_sf1.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃     HEAD ┃ intermeidate-result-blocked-approach ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 1     │ 124.78ms │                             130.74ms │    no change │
│ QQuery 2     │  24.32ms │                              23.65ms │    no change │
│ QQuery 3     │  35.37ms │                              35.46ms │    no change │
│ QQuery 4     │  20.87ms │                              20.87ms │    no change │
│ QQuery 5     │  54.85ms │                              57.66ms │ 1.05x slower │
│ QQuery 6     │  12.21ms │                              12.64ms │    no change │
│ QQuery 7     │  99.22ms │                             102.82ms │    no change │
│ QQuery 8     │  26.11ms │                              25.50ms │    no change │
│ QQuery 9     │  63.11ms │                              64.15ms │    no change │
│ QQuery 10    │  57.98ms │                              59.17ms │    no change │
│ QQuery 11    │  13.04ms │                              13.20ms │    no change │
│ QQuery 12    │  43.72ms │                              44.49ms │    no change │
│ QQuery 13    │  28.90ms │                              29.45ms │    no change │
│ QQuery 14    │   9.78ms │                              10.58ms │ 1.08x slower │
│ QQuery 15    │  26.05ms │                              25.35ms │    no change │
│ QQuery 16    │  23.45ms │                              23.66ms │    no change │
│ QQuery 17    │  95.93ms │                              97.78ms │    no change │
│ QQuery 18    │ 240.22ms │                             238.96ms │    no change │
│ QQuery 19    │  27.56ms │                              28.63ms │    no change │
│ QQuery 20    │  38.46ms │                              38.79ms │    no change │
│ QQuery 21    │ 173.00ms │                             168.56ms │    no change │
│ QQuery 22    │  18.15ms │                              17.81ms │    no change │
└──────────────┴──────────┴──────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 1257.09ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 1269.90ms │
│ Average Time (HEAD)                                 │   57.14ms │
│ Average Time (intermeidate-result-blocked-approach) │   57.72ms │
│ Queries Faster                                      │         0 │
│ Queries Slower                                      │         2 │
│ Queries with No Change                              │        20 │
└─────────────────────────────────────────────────────┴───────────┘

Emmm... As expected the new added query is not convered, I think I should submit an new pr for adding the query to extended.sql for checking the improvement... Just wait a minute.

SELECT "WatchID", MIN("ResolutionWidth"), MAX("ResolutionWidth"), SUM("IsRefresh") FROM hits GROUP BY "WatchID" ORDER BY "WatchID" DESC LIMIT 10;

@alamb
Copy link
Contributor

alamb commented May 3, 2025

I am back from holiday, and continue to work on this today.

Welcome back!

Emmm... As expected the new added query is not convered, I think I should submit an new pr for adding the query to extended.sql for checking the improvement... Just wait a minute.

Makes sense

And actually still don't have such a simple query can show the improvement now...

What would be required to improve the performance for one or more of the real clickbench queries? Implementing group management for other data types?

Given we have past evidence this approach will work I think we could merge it before the queries really sped up. My big concern is that we have a plan to eventually avoid both single and multi blocked management

@alamb
Copy link
Contributor

alamb commented May 3, 2025

🤖 ./gh_compare_branch.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing intermeidate-result-blocked-approach (ff9c3ad) to 74dc419 diff
Benchmarks: tpch_mem clickbench_partitioned clickbench_extended
Results will be posted here when complete

@Rachelint
Copy link
Contributor Author

Rachelint commented May 3, 2025

What would be required to improve the performance for one or more of the real clickbench queries? Implementing group management for other data types?

Yes.
Usually high cardinality aggregation can get improvement from, like q16~q18 and q32(group by UserID or WatchID).

But we need to implement group management for multiple data types for GroupValues, or for multiple GroupAccumulator, for enabling the optimization in such queries.

I think it may be too complex for the initial pr...

@Rachelint
Copy link
Contributor Author

Rachelint commented May 3, 2025

Given we have past evidence this approach will work I think we could merge it before the queries really sped up. My big concern is that we have a plan to eventually avoid both single and multi blocked management

The mainly hard point for removing single management is about sorted aggregation:

  • We need Emit::First(exactly n) for sorted aggregation
  • Supporting Emit::First(exactly n) in blocked management is actually too expansive...

I try to reuse codes as much as possible to ease this problem (like NullState, and the refactor for GroupValuesPrimitive::intern).

Actually I encounter the same problem in #12996 ... I think maybe it is a common problem about how to support sorted aggregation?

I suspect if we can remove Emit::First(exactly n)? It is non-trivial even now, I am sure we can remove it in spilling path, and seems possible to remove it in sorted path?

@alamb
Copy link
Contributor

alamb commented May 3, 2025

🤖: Benchmark completed

Details

Comparing HEAD and intermeidate-result-blocked-approach
--------------------
Benchmark clickbench_extended.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃       Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 0     │  1937.34ms │                            1929.54ms │    no change │
│ QQuery 1     │   664.33ms │                             719.97ms │ 1.08x slower │
│ QQuery 2     │  1395.20ms │                            1411.13ms │    no change │
│ QQuery 3     │   712.50ms │                             710.80ms │    no change │
│ QQuery 4     │  1477.28ms │                            1475.06ms │    no change │
│ QQuery 5     │ 15310.28ms │                           15186.79ms │    no change │
│ QQuery 6     │  2049.34ms │                            2066.82ms │    no change │
└──────────────┴────────────┴──────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 23546.29ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 23500.10ms │
│ Average Time (HEAD)                                 │  3363.76ms │
│ Average Time (intermeidate-result-blocked-approach) │  3357.16ms │
│ Queries Faster                                      │          0 │
│ Queries Slower                                      │          1 │
│ Queries with No Change                              │          6 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃       HEAD ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0     │     2.53ms │                               2.09ms │ +1.21x faster │
│ QQuery 1     │    35.62ms │                              39.76ms │  1.12x slower │
│ QQuery 2     │    89.48ms │                              92.73ms │     no change │
│ QQuery 3     │   100.30ms │                             100.22ms │     no change │
│ QQuery 4     │   750.96ms │                             754.32ms │     no change │
│ QQuery 5     │   833.28ms │                             857.42ms │     no change │
│ QQuery 6     │     2.06ms │                               2.08ms │     no change │
│ QQuery 7     │    40.36ms │                              42.52ms │  1.05x slower │
│ QQuery 8     │   924.79ms │                             902.95ms │     no change │
│ QQuery 9     │  1209.71ms │                            1224.03ms │     no change │
│ QQuery 10    │   264.71ms │                             273.51ms │     no change │
│ QQuery 11    │   302.87ms │                             313.03ms │     no change │
│ QQuery 12    │   917.10ms │                             899.06ms │     no change │
│ QQuery 13    │  1338.05ms │                            1255.47ms │ +1.07x faster │
│ QQuery 14    │   833.92ms │                             846.94ms │     no change │
│ QQuery 15    │  1030.69ms │                            1073.94ms │     no change │
│ QQuery 16    │  1724.70ms │                            1732.73ms │     no change │
│ QQuery 17    │  1605.96ms │                            1581.98ms │     no change │
│ QQuery 18    │  3069.41ms │                            3072.93ms │     no change │
│ QQuery 19    │    83.51ms │                              85.65ms │     no change │
│ QQuery 20    │  1123.00ms │                            1140.04ms │     no change │
│ QQuery 21    │  1333.50ms │                            1336.50ms │     no change │
│ QQuery 22    │  2175.85ms │                            2185.26ms │     no change │
│ QQuery 23    │  8284.06ms │                            8470.20ms │     no change │
│ QQuery 24    │   461.57ms │                             485.77ms │  1.05x slower │
│ QQuery 25    │   384.10ms │                             394.93ms │     no change │
│ QQuery 26    │   531.30ms │                             545.07ms │     no change │
│ QQuery 27    │  1670.90ms │                            1705.20ms │     no change │
│ QQuery 28    │ 12167.48ms │                           12606.28ms │     no change │
│ QQuery 29    │   526.92ms │                             533.47ms │     no change │
│ QQuery 30    │   819.98ms │                             848.41ms │     no change │
│ QQuery 31    │   869.73ms │                             868.43ms │     no change │
│ QQuery 32    │  2619.87ms │                            2735.34ms │     no change │
│ QQuery 33    │  3314.19ms │                            3383.18ms │     no change │
│ QQuery 34    │  3382.94ms │                            3381.46ms │     no change │
│ QQuery 35    │  1271.48ms │                            1274.86ms │     no change │
│ QQuery 36    │   127.20ms │                             126.03ms │     no change │
│ QQuery 37    │    57.38ms │                              58.27ms │     no change │
│ QQuery 38    │   125.72ms │                             127.26ms │     no change │
│ QQuery 39    │   198.86ms │                             202.15ms │     no change │
│ QQuery 40    │    48.58ms │                              49.01ms │     no change │
│ QQuery 41    │    47.74ms │                              46.89ms │     no change │
│ QQuery 42    │    38.64ms │                              41.29ms │  1.07x slower │
└──────────────┴────────────┴──────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 56740.96ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 57698.64ms │
│ Average Time (HEAD)                                 │  1319.56ms │
│ Average Time (intermeidate-result-blocked-approach) │  1341.83ms │
│ Queries Faster                                      │          2 │
│ Queries Slower                                      │          4 │
│ Queries with No Change                              │         37 │
└─────────────────────────────────────────────────────┴────────────┘
--------------------
Benchmark tpch_mem_sf1.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃     HEAD ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1     │ 124.49ms │                             125.48ms │     no change │
│ QQuery 2     │  23.64ms │                              23.86ms │     no change │
│ QQuery 3     │  34.94ms │                              35.04ms │     no change │
│ QQuery 4     │  20.94ms │                              21.46ms │     no change │
│ QQuery 5     │  54.67ms │                              56.82ms │     no change │
│ QQuery 6     │  12.22ms │                              12.09ms │     no change │
│ QQuery 7     │ 107.09ms │                             100.00ms │ +1.07x faster │
│ QQuery 8     │  25.48ms │                              27.73ms │  1.09x slower │
│ QQuery 9     │  61.36ms │                              60.88ms │     no change │
│ QQuery 10    │  57.44ms │                              58.40ms │     no change │
│ QQuery 11    │  13.19ms │                              13.10ms │     no change │
│ QQuery 12    │  44.39ms │                              44.66ms │     no change │
│ QQuery 13    │  29.29ms │                              29.01ms │     no change │
│ QQuery 14    │   9.98ms │                               9.77ms │     no change │
│ QQuery 15    │  25.86ms │                              25.80ms │     no change │
│ QQuery 16    │  23.58ms │                              23.34ms │     no change │
│ QQuery 17    │  93.78ms │                              99.44ms │  1.06x slower │
│ QQuery 18    │ 233.64ms │                             243.04ms │     no change │
│ QQuery 19    │  26.31ms │                              28.12ms │  1.07x slower │
│ QQuery 20    │  37.88ms │                              37.07ms │     no change │
│ QQuery 21    │ 164.99ms │                             171.58ms │     no change │
│ QQuery 22    │  18.39ms │                              17.12ms │ +1.07x faster │
└──────────────┴──────────┴──────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                   ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                   │ 1243.55ms │
│ Total Time (intermeidate-result-blocked-approach)   │ 1263.81ms │
│ Average Time (HEAD)                                 │   56.52ms │
│ Average Time (intermeidate-result-blocked-approach) │   57.45ms │
│ Queries Faster                                      │         2 │
│ Queries Slower                                      │         3 │
│ Queries with No Change                              │        17 │
└─────────────────────────────────────────────────────┴───────────┘

@Rachelint
Copy link
Contributor Author

Rachelint commented May 3, 2025

@alamb I have submitted an pr about new added query for this pr #15936

After merging #15936 , the benchmark result in my local (as expected, Q7 get faster):

--------------------
Benchmark clickbench_extended.json
--------------------
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query        ┃       main ┃ intermeidate-result-blocked-approach ┃        Change ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0     │  1963.62ms │                            1934.86ms │     no change │
│ QQuery 1     │  1172.47ms │                            1098.65ms │ +1.07x faster │
│ QQuery 2     │  2409.61ms │                            2296.81ms │     no change │
│ QQuery 3     │   969.68ms │                            1040.13ms │  1.07x slower │
│ QQuery 4     │  2953.83ms │                            2975.20ms │     no change │
│ QQuery 5     │ 32846.39ms │                           32052.44ms │     no change │
│ QQuery 6     │  5263.42ms │                            5188.99ms │     no change │
│ QQuery 7     │  7980.62ms │                            7246.23ms │ +1.10x faster │
└──────────────┴────────────┴──────────────────────────────────────┴───────────────┘

@Rachelint Rachelint force-pushed the intermeidate-result-blocked-approach branch from 7e07e81 to 426e2ee Compare May 3, 2025 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
common Related to common crate core Core DataFusion crate documentation Improvements or additions to documentation functions Changes to functions implementation logical-expr Logical plan and expressions physical-expr Changes to the physical-expr crates sqllogictest SQL Logic Tests (.slt)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants