You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I briefly looked at the descriptions of these optimizations. For example, the method of dynamically handling the "order by limit" process using statistics is really cool! @alamb
Idea
But I have some new ideas that seem to be more universally applicable to order by limit(q23):
┌──────────────────────────────────────┐
│ [Step 1] Filter RowGroups │
│ - Use Parquet metadata to skip RGs │
│ WHERERG.min(EventTime) > cutoff │
└───────────────────┬──────────────────┘
↓
┌──────────────────────────────────────┐
│ [Step 2] Read EventTime + Filter │
│ - Scan EventTime column in valid RGs │
│ - Sort values → Track top 10 rows │
└───────────────────┬──────────────────┘
↓
┌──────────────────────────────────────┐
│ [Step 3] Record Row Locations │
│ - Map top 10 EventTime to physical │
│ positions (RG_ID + Row_Offset) │
└───────────────────┬──────────────────┘
↓
┌──────────────────────────────────────┐
│ [Step 4] Fetch 10 Rows │
│ - Directly read rows from Parquet │
│ via recorded positions (non-seq) │
└───────────────────┬──────────────────┘
↓
Final Result
Explore
Currently, q23 takes approximately 6 seconds to execute. I have confirmed that DataFusion does not have the aforementioned optimizations and still scans a very large number of rows and columns. By the way, is there a convenient way in datafusion-cli to view statistics on the number of rows and columns scanned? Currently, I directly print the batch information in the Like expression, which gives the following output (it seems endless, and the amount of data being scanned appears to be very large, all with exactly 105 columns):
Some concerns
Parquet is composed of RowGroups. Is it difficult to read an individual page? In my previous work, I’ve seen optimizations for this scenario (based on DataFusion), but it used a custom columnar storage format, which was easier to implement. At that time, when working with very large datasets (similar to the hits dataset), the query time for "order by limit" was reduced to around 2 seconds.
Summary
The reading process of the entire data can be delayed by using "order by" on columns, which is very effective for the "order by limit" scenario. I'm not sure if DataFusion is currently doing this.
Thank you @acking-you for the idea. Does it similar to parquet filter pushdown? We are already trying to make it default. #3463
With parquet filter pushdown, we will only scan the filtered pages, but the topk filter pushdown is still in progress.
This optimization targets the select * xxx order by limit scenario, where it can bring significant improvements. If we only push down the filter, it won't achieve the effect of materializing only the full columns within the limit rows. Therefore, for the order by limit scenario, we need to implement lazy materialization of columns.
The approach is quite easy to understand. It involves completing the sorting by only reading the order by columns and then performing a full scan to read the required "limit" rows.
Take select * from data order by timestamp desc limit 10 as an example
the most straightforward execution process for "order by limit" might look like the following:
In my previous attempt link, I found that in order to read 10 rows of data, DataFusion would end up scanning an additional 104 columns, which is a significant overhead. I believe the approach would be very helpful for this scenario.
Thank you for your hint. I haven't looked into this part of the code yet. I only reviewed the optimization method you described in #15037. It seems that there is no mention of deferred materialization for "order by limit" (perhaps I missed it since the content of the issue is quite long). So, have we considered optimizing "order by limit" in two phases? I'm planning to review and study the PR you mentioned over the weekend. Thanks again for your reply.
DataFusion already does late materialization: if orders filters by least to most expensive, then scans only the columns that the filter needs. Once it applies all filters it then materializes the projection. It's not the default yet but it will be soon. Please see #3463 which @zhuqi-lucas linked to above.
DataFusion already does late materialization: if orders filters by least to most expensive, then scans only the columns that the filter needs. Once it applies all filters it then materializes the projection. It's not the default yet but it will be soon. Please see #3463 which @zhuqi-lucas linked to above.
I'm sorry. I thought the late materialization was for filter column without considering order by column. This is my fault. I should have looked deeper.
Currently, q23 takes approximately 6 seconds to execute. I have confirmed that DataFusion does not have the aforementioned optimizations and still scans a very large number of rows and columns. By the way, is there a convenient way in datafusion-cli to view statistics on the number of rows and columns scanned? Currently, I directly print the batch information in the Like expression, which gives the following output (it seems endless, and the amount of data being scanned appears to be very large, all with exactly 105 columns):
@acking-you I agree with your analysis and arrived at a similar conclusion in this ticket:
It seems that there is no mention of deferred materialization for "order by limit" (perhaps I missed it since the content of the issue is quite long). So, have we considered optimizing "order by limit" in two phases? I'm planning to review and study the PR you mentioned over the weekend. Thanks again for your reply.
I also agree The deferred materialization is key to improving performance massively. I believe this is the effect of #3463 though it does not use that term
Exciting news! We've merged TopK filter pushdown. As we've moved along we've found a lot of neat little optimizations - I think a blog post is in order.
Reacted by Jonathan Chen, suibianwanwan, LB7666, Andrew Lamb and xudong.w
Activity
adriangb commentedon Apr 1, 2025
Adding #15534
adriangb commentedon Apr 3, 2025
I've started breaking out the work:
ParquetSourceacking-you commentedon Apr 17, 2025
I briefly looked at the descriptions of these optimizations. For example, the method of dynamically handling the "order by limit" process using statistics is really cool! @alamb
Idea
But I have some new ideas that seem to be more universally applicable to
order by limit(q23):Explore
Currently, q23 takes approximately 6 seconds to execute. I have confirmed that DataFusion does not have the aforementioned optimizations and still scans a very large number of rows and columns. By the way, is there a convenient way in
datafusion-clito view statistics on the number of rows and columns scanned? Currently, I directly print the batch information in theLikeexpression, which gives the following output (it seems endless, and the amount of data being scanned appears to be very large, all with exactly 105 columns):Some concerns
Parquet is composed of RowGroups. Is it difficult to read an individual page? In my previous work, I’ve seen optimizations for this scenario (based on DataFusion), but it used a custom columnar storage format, which was easier to implement. At that time, when working with very large datasets (similar to the hits dataset), the query time for "order by limit" was reduced to around 2 seconds.
Summary
The reading process of the entire data can be delayed by using "order by" on columns, which is very effective for the "order by limit" scenario. I'm not sure if DataFusion is currently doing this.
zhuqi-lucas commentedon Apr 17, 2025
Thank you @acking-you for the idea. Does it similar to parquet filter pushdown? We are already trying to make it default.
#3463
With parquet filter pushdown, we will only scan the filtered pages, but the topk filter pushdown is still in progress.
acking-you commentedon Apr 17, 2025
This optimization targets the
select * xxx order by limitscenario, where it can bring significant improvements. If we only push down the filter, it won't achieve the effect of materializing only the full columns within the limit rows. Therefore, for theorder by limitscenario, we need to implement lazy materialization of columns.The approach is quite easy to understand. It involves completing the sorting by only reading the
order by columnsand then performing a full scan to read the required "limit" rows.Take
select * from data order by timestamp desc limit 10as an examplethe most straightforward execution process for "order by limit" might look like the following:
The effect after having delayed materialization of non-ordered columns is as follows:
My opinion
In my previous attempt link, I found that in order to read 10 rows of data, DataFusion would end up scanning an additional 104 columns, which is a significant overhead. I believe the approach would be very helpful for this scenario.
acking-you commentedon Apr 18, 2025
I also noticed that recently, a PR was merged in ClickHouse that does exactly what was described above: ClickHouse/ClickHouse#55518, with the corresponding issue: ClickHouse/ClickHouse#45868. @zhuqi-lucas
adriangb commentedon Apr 18, 2025
@acking-you have you seen #15301?
acking-you commentedon Apr 18, 2025
Thank you for your hint. I haven't looked into this part of the code yet. I only reviewed the optimization method you described in #15037. It seems that there is no mention of deferred materialization for "order by limit" (perhaps I missed it since the content of the issue is quite long). So, have we considered optimizing "order by limit" in two phases? I'm planning to review and study the PR you mentioned over the weekend. Thanks again for your reply.
adriangb commentedon Apr 18, 2025
DataFusion already does late materialization: if orders filters by least to most expensive, then scans only the columns that the filter needs. Once it applies all filters it then materializes the projection. It's not the default yet but it will be soon. Please see #3463 which @zhuqi-lucas linked to above.
acking-you commentedon Apr 18, 2025
I'm sorry. I thought the late materialization was for filter column without considering order by column. This is my fault. I should have looked deeper.
adriangb commentedon Apr 18, 2025
Well the point of this recent work is to create filters from the order by clause :)
alamb commentedon Apr 19, 2025
@acking-you I agree with your analysis and arrived at a similar conclusion in this ticket:
I also agree The deferred materialization is key to improving performance massively. I believe this is the effect of #3463 though it does not use that term
So TLDR is by combing the following two items
filter_pushdown) by default #3463I think DataFusion will have the equivalent of materialized filter
adriangb commentedon Jun 18, 2025
Exciting news! We've merged TopK filter pushdown. As we've moved along we've found a lot of neat little optimizations - I think a blog post is in order.
adriangb commentedon Jun 18, 2025
I added #16435
[-][Epic] A collection of dynamic filtering related items[/-][+][Epic] Dynamic filtering related items[/+]