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
Is your feature request related to a problem or challenge?
When looking at some Samply profiles of ClickBench queries on my laptop, it appears there are several times where processing stalls due to parsing parquet metadata:
datafusion-cli -c "SELECT \"WatchID\", \"ClientIP\", COUNT(*) AS c, SUM(\"IsRefresh\"), AVG(\"ResolutionWidth\") FROM 'data/hits.parquet' WHERE \"SearchPhrase\" <> '' GROUP BY \"WatchID\", \"ClientIP\" ORDER BY c DESC LIMIT 10;"
Profile wiht samply (you must build datafusion-cli with `--profile profiling):
samply record datafusion-cli -c "SELECT \"WatchID\", \"ClientIP\", COUNT(*) AS c, SUM(\"IsRefresh\"), AVG(\"ResolutionWidth\") FROM 'data/hits.parquet' WHERE \"SearchPhrase\" <> '' GROUP BY \"WatchID\", \"ClientIP\" ORDER BY c DESC LIMIT 10;"
I am working on this for dft right now actually and I plan on integrating it into the observability feature that I have been working on (where different observability metrics are exposed as tables). Specifically, I made a new MapTable that allows querying and updating different types of map data structures (for now just an IndexMap but i plan to try others like BTreeMap as well). The idea is that the same map that is used for caching both file and parquet metadata can be queried to get details such as when the entry was created, last update, # of hits, etc.
I would be happy to share / upstream any work I do on this if there is interest.
I would be happy to share / upstream any work I do on this if there is interest.
Thanks @matthewmturner -- what I think would be really valuable is if you could prove/disprove the theory that caching parsed metadata improves local TPCH performance
I think it is already pretty well understood that avoiding object store requests to remote object stores helps, and many downstream systems already do this (influx, pydantic, etc) .
However, we haven't built in caching for metadata locally because I think we assumed the overhead wasn't very big compared to the complexity of a built in metadata cache -- maybe we should re-evalute that assesment
As a DataFusion user, I’m wondering if the Parquet footer could be cached. This blog mentioned footer caching. It is a bit confusing to me.
(I’m also involved in promoting footer caching in cuDF, which is why I mentioned this issue there as well. In cuDF, Thrift decoding is a bottleneck on the CPU due to its single-threaded implementation, often leaving the GPU idle.)
I am thinking adding the footer caching thing to datafusion-cli might be a nice way to improve performance and make it easier to see how to add these features
@alamb is this still something that would benefit upstream Datafusion?
I've implemented the caching of Parquet metadata after noticing that a large amount of time spent on our workloads comes from (re)reading it, as pointed by metadata_load_time. This time becomes noticeable in large files that have a large number of pages, where most of the metadata reading times comes from retrieving the page indexes.
Here are some results:
Simple reads
+----------------------------------------------------+
| 1k simple queries (select where k = ...) |
+-----------+------------+---------+-----------------+
| # of Rows | Not cached | Cached | |
+-----------+------------+---------+-----------------+
| 100k | 1.9447s | 1.1773s | 1.6517x faster |
+-----------+------------+---------+-----------------+
| 100M | 21.2953s | 1.6018s | 13.2943x faster |
+-----------+------------+---------+-----------------+
As for TPC-H, the improvements won't be as noticeable given the queries are more complex, but they will be there. Here are the metadata_load_times of a TPC-H query (sf=10):
As for the implementation, it relies on the session's CacheManager and a custom CachedParquetFileReaderFactory. The metadata caching can be set independently for each Parquet file, using ParquetReadOptions, and is invalidated when the underlying file is modified. I would be happy to open a PR, but I still have some questions:
For the CacheManager to remain generic, I created a pub type FileMetadata = dyn Any + Send + Sync; to represent metadata, which essentially can end up storing anything. Unlike the other information stored (Statistics and ObjectMeta), there isn't a common type for embedded metadata. Is this the right approach, or should the CacheManager be aware of ParquetMetaData?
Unlike the other CacheManager parameters, which I believe are exclusively user-provided, I think it would make sense for the metadata cache be populated with a DefaultFilesMetadataCache, so its easier to enable caching just with ParquetReadOptions or set .... Does this make sense?
I would love to help review / get this feature merged in
For the CacheManager to remain generic, I created a pub type FileMetadata = dyn Any + Send + Sync; to represent metadata, which essentially can end up storing anything. Unlike the other information stored (Statistics and ObjectMeta), there isn't a common type for embedded metadata. Is this the right approach, or should the CacheManager be aware of ParquetMetaData?
I think keeping it generic makes the most sense because as you say there isn't something clearly that maps to all file formats
Unlike the other CacheManager parameters, which I believe are exclusively user-provided, I think it would make sense for the metadata cache be populated with a DefaultFilesMetadataCache, so its easier to enable caching just with ParquetReadOptions or set .... Does this make sense?
It sounds so but I don't fully understand the proposal so I may me missing someting
Activity
matthewmturner commentedon Apr 5, 2025
I am working on this for
dftright now actually and I plan on integrating it into the observability feature that I have been working on (where different observability metrics are exposed as tables). Specifically, I made a newMapTablethat allows querying and updating different types of map data structures (for now just anIndexMapbut i plan to try others likeBTreeMapas well). The idea is that the same map that is used for caching both file and parquet metadata can be queried to get details such as when the entry was created, last update, # of hits, etc.I would be happy to share / upstream any work I do on this if there is interest.
alamb commentedon Apr 6, 2025
Thanks @matthewmturner -- what I think would be really valuable is if you could prove/disprove the theory that caching parsed metadata improves local TPCH performance
I think it is already pretty well understood that avoiding object store requests to remote object stores helps, and many downstream systems already do this (influx, pydantic, etc) .
However, we haven't built in caching for metadata locally because I think we assumed the overhead wasn't very big compared to the complexity of a built in metadata cache -- maybe we should re-evalute that assesment
adriangb commentedon May 7, 2025
I'll mention that we now avoid reading metadata entirely for a lot of queries using an approach along the lines of #15585
JigaoLuo commentedon Jun 25, 2025
As a DataFusion user, I’m wondering if the Parquet footer could be cached. This blog mentioned footer caching. It is a bit confusing to me.
(I’m also involved in promoting footer caching in cuDF, which is why I mentioned this issue there as well. In cuDF, Thrift decoding is a bottleneck on the CPU due to its single-threaded implementation, often leaving the GPU idle.)
alamb commentedon Jun 25, 2025
DataFusion (and
datafusion-cli) doesn't do footer caching by default -- you can see this here:datafusion-cliwhen reading from remote storage #16365You can do it and most high performance integrations (like InfluxDB and pydantic) absolutely do. An example of doing it is here:
https://github.com/apache/datafusion/blob/main/datafusion-examples/examples/advanced_parquet_index.rs
I am thinking adding the footer caching thing to datafusion-cli might be a nice way to improve performance and make it easier to see how to add these features
nuno-faria commentedon Jul 28, 2025
@alamb is this still something that would benefit upstream Datafusion?
I've implemented the caching of Parquet metadata after noticing that a large amount of time spent on our workloads comes from (re)reading it, as pointed by
metadata_load_time. This time becomes noticeable in large files that have a large number of pages, where most of the metadata reading times comes from retrieving the page indexes.Here are some results:
Simple reads
Partial explain of a
DataSourceExec:TPC-H
metadata_load_timesof a TPC-H query (sf=10):As for the implementation, it relies on the session's
CacheManagerand a customCachedParquetFileReaderFactory. The metadata caching can be set independently for each Parquet file, usingParquetReadOptions, and is invalidated when the underlying file is modified. I would be happy to open a PR, but I still have some questions:CacheManagerto remain generic, I created apub type FileMetadata = dyn Any + Send + Sync;to represent metadata, which essentially can end up storing anything. Unlike the other information stored (StatisticsandObjectMeta), there isn't a common type for embedded metadata. Is this the right approach, or should theCacheManagerbe aware ofParquetMetaData?CacheManagerparameters, which I believe are exclusively user-provided, I think it would make sense for the metadata cache be populated with aDefaultFilesMetadataCache, so its easier to enable caching just withParquetReadOptionsorset .... Does this make sense?alamb commentedon Jul 28, 2025
13x faster 👏
I would love to help review / get this feature merged in
I think keeping it generic makes the most sense because as you say there isn't something clearly that maps to all file formats
It sounds so but I don't fully understand the proposal so I may me missing someting