Repository: vortex-data/vortex
Pull request #3293: duckdb: free layout readers after usage
Author: login: 0ax1
Labels: name: changelog/performance
description: A performance improvement
Created: 2025-05-14T12:33:41Z | Merged: 2025-05-20T10:00:59Z



Diff:
diff --git a/duckdb-vortex/src/include/vortex_common.hpp b/duckdb-vortex/src/include/vortex_common.hpp
index b84d5930e59..306614aa0a2 100644
--- a/duckdb-vortex/src/include/vortex_common.hpp
+++ b/duckdb-vortex/src/include/vortex_common.hpp
@@ -97,7 +97,7 @@ struct Array {
 };
 
 struct ArrayIterator {
-	explicit ArrayIterator(vx_array_iter *array_iter) : array_iter(array_iter) {
+	explicit ArrayIterator(vx_array_iterator *array_iter) : array_iter(array_iter) {
 	}
 
 	~ArrayIterator() {
@@ -114,7 +114,7 @@ struct ArrayIterator {
 		return duckdb::make_uniq<Array>(array);
 	}
 
-	vx_array_iter *array_iter;
+	vx_array_iterator *array_iter;
 };
 
 struct ArrayStreamSink {
diff --git a/duckdb-vortex/src/include/vortex_error.hpp b/duckdb-vortex/src/include/vortex_error.hpp
index 040c650b05a..b41565df86d 100644
--- a/duckdb-vortex/src/include/vortex_error.hpp
+++ b/duckdb-vortex/src/include/vortex_error.hpp
@@ -20,7 +20,7 @@ template <typename Func>
 auto Try(Func func) {
 	vx_error *error = nullptr;
 	// Handle both void and non-void return types.
-	if constexpr (std::is_void_v<std::invoke_result_t<Func, vx_error**>>) {
+	if constexpr (std::is_void_v<std::invoke_result_t<Func, vx_error **>>) {
 		func(&error);
 		HandleError(error);
 	} else {
diff --git a/duckdb-vortex/src/include/vortex_layout_reader.hpp b/duckdb-vortex/src/include/vortex_layout_reader.hpp
index f8009dfb8ed..99ad14a8e2f 100644
--- a/duckdb-vortex/src/include/vortex_layout_reader.hpp
+++ b/duckdb-vortex/src/include/vortex_layout_reader.hpp
@@ -19,7 +19,7 @@ class LayoutReader {
 		return std::make_shared<LayoutReader>(reader);
 	}
 
-	vx_array_iter *Scan(const vx_file_scan_options *options) {
+	vx_array_iterator *Scan(const vx_file_scan_options *options) {
 		return Try([&](auto err) { return vx_layout_reader_scan(this->reader, options, err); });
 	}
 
diff --git a/duckdb-vortex/src/vortex_scan.cpp b/duckdb-vortex/src/vortex_scan.cpp
index 1bdd60af1e0..3859934537e 100644
--- a/duckdb-vortex/src/vortex_scan.cpp
+++ b/duckdb-vortex/src/vortex_scan.cpp
@@ -2,8 +2,10 @@
 
 #include <memory>
 #include <mutex>
+#include <queue>
 #include <regex>
 #include <thread>
+#include <vector>
 
 #include "duckdb/common/exception.hpp"
 #include "duckdb/common/helper.hpp"
@@ -70,7 +72,11 @@ struct ScanLocalState : public LocalTableFunctionState {
 	unique_ptr<Array> currently_scanned_array;
 	unique_ptr<ArrayIterator> array_iterator;
 	unique_ptr<ConversionCache> conversion_cache;
-	duckdb_moodycamel::ConcurrentQueue<ScanPartition> scan_partitions {8192};
+
+	std::queue<ScanPartition> scan_partitions;
+
+	// Thread local file.
+	std::optional<idx_t> thread_local_file_idx;
 };
 
 struct ScanGlobalState : public GlobalTableFunctionState {
@@ -84,7 +90,7 @@ struct ScanGlobalState : public GlobalTableFunctionState {
 	std::string filter_str;
 
 	// Limited to indicate progress in `table_scan_progress`.
-	std::atomic_uint32_t partitons_processed;
+	std::atomic_uint32_t partitions_processed;
 	std::atomic_uint32_t partitons_total;
 
 	// Number of files which have are fully partitioned.
@@ -231,6 +237,15 @@ static unique_ptr<FileReader> OpenFileAndVerify(FileSystem &fs, const std::strin
 	return file;
 }
 
+static bool PinFileToThread(ScanGlobalState &global_state) {
+	// This is an approximation to determine whether we should switch to
+	// distributing partitions of the same file across threads and does
+	// not need to be exact in terms of how many threads DuckDB actually uses.
+	const auto thread_count = std::thread::hardware_concurrency();
+	const auto file_count = global_state.expanded_files.size();
+	return (file_count - global_state.files_partitioned) > thread_count;
+}
+
 static void CreateScanPartitions(ClientContext &context, const BindData &bind, ScanGlobalState &global_state,
                                  ScanLocalState &local_state, uint64_t file_idx, unique_ptr<FileReader> &file_reader) {
 	const auto file_name = global_state.expanded_files[file_idx];
@@ -248,21 +263,24 @@ static void CreateScanPartitions(ClientContext &context, const BindData &bind, S
 
 	const auto partition_count = std::max(static_cast<uint64_t>(1), row_count / partition_size);
 	global_state.partitons_total += partition_count;
-
-	// Pin threads to files as long as there more files than threads left to process.
-	const bool pin_file_to_thread = (file_count - global_state.files_partitioned) > thread_count;
-	auto &partitions_queue = pin_file_to_thread ? local_state.scan_partitions : global_state.scan_partitions;
+	local_state.thread_local_file_idx = file_idx;
 
 	for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
-
-		partitions_queue.enqueue(ScanPartition {
+		const auto scan_partition = ScanPartition {
 		    .file_idx = file_idx,
 		    .start_row = partition_idx * partition_size,
 		    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
-		});
+		};
+
+		if (PinFileToThread(global_state)) {
+			local_state.scan_partitions.push(scan_partition);
+		} else {
+			global_state.scan_partitions.enqueue(scan_partition);
+		}
 	}
 
 	global_state.files_partitioned += 1;
+	D_ASSERT(global_state.files_partitioned <= global_state.expanded_files.size());
 }
 
 static unique_ptr<ArrayIterator> OpenArrayIter(ScanGlobalState &global_state,
@@ -283,26 +301,32 @@ static unique_ptr<ArrayIterator> OpenArrayIter(ScanGlobalState &global_state,
 
 // Assigns the next array from the array stream.
 //
-// Returns true if a new array was assigned. Returns false otherwise.
+// Returns true if a new array was assigned, false otherwise.
 static bool GetNextArray(ClientContext &context, const BindData &bind_data, ScanGlobalState &global_state,
                          ScanLocalState &local_state, DataChunk &output) {
 
+	// Try to deque a partition off the thread local queue.
+	auto try_dequeue = [&](ScanPartition &scan_partition) {
+		if (local_state.scan_partitions.empty()) {
+			return false;
+		}
+
+		scan_partition = local_state.scan_partitions.front();
+		local_state.scan_partitions.pop();
+		return true;
+	};
+
 	if (local_state.array_iterator == nullptr) {
 		ScanPartition partition;
 
-		// Try to pop a partition off the thread local queue first.
-		if (bool success = (local_state.scan_partitions.try_dequeue(partition) ||
-		                    global_state.scan_partitions.try_dequeue(partition));
-		    !success) {
+		if (bool success = (try_dequeue(partition) || global_state.scan_partitions.try_dequeue(partition)); !success) {
 
-			// Check if all files have been partitioned.
+			// Check whether all partitions have been processed.
 			if (global_state.files_partitioned == global_state.expanded_files.size()) {
 
 				// A new partition might have been created after the first pop. Therefore,
-				// one more pop is necessary to be sure no more partitions are left to process.
+				// one more pop is necessary to ensure no more partitions are left to process.
 				if (success = global_state.scan_partitions.try_dequeue(partition); !success) {
-
-					// The queue is empty and all files had been partitioned.
 					global_state.finished = true;
 					return false;
 				}
@@ -313,8 +337,9 @@ static bool GetNextArray(ClientContext &context, const BindData &bind_data, Scan
 			}
 		}
 
-		global_state.partitons_processed += 1;
-		std::shared_ptr<LayoutReader> layout_reader = global_state.layout_readers[partition.file_idx];
+		// Layout readers are safe to share across threads for reading. Further, they
+		// are created before pushing partitions of the corresponing files into a queue.
+		auto layout_reader = global_state.layout_readers[partition.file_idx];
 		local_state.array_iterator = OpenArrayIter(global_state, layout_reader, partition);
 	}
 
@@ -323,6 +348,8 @@ static bool GetNextArray(ClientContext &context, const BindData &bind_data, Scan
 
 	if (local_state.currently_scanned_array == nullptr) {
 		local_state.array_iterator = nullptr;
+		global_state.partitions_processed += 1;
+
 		return false;
 	}
 
@@ -342,6 +369,12 @@ static void VortexScanFunction(ClientContext &context, TableFunctionInput &data,
 				return;
 			}
 
+			// Free layout readers as long as we pin files to threads.
+			if (local_state.scan_partitions.empty() && local_state.thread_local_file_idx.has_value()) {
+				global_state.layout_readers[local_state.thread_local_file_idx.value()] = nullptr;
+				local_state.thread_local_file_idx.reset();
+			}
+
 			// Create new scan partitions in case the queue is empty.
 			if (auto file_idx = global_state.next_file_idx.fetch_add(1);
 			    file_idx < global_state.expanded_files.size()) {
@@ -453,7 +486,7 @@ void RegisterScanFunction(DatabaseInstance &instance) {
 	vortex_scan.table_scan_progress = [](ClientContext &context, const FunctionData *bind_data,
 	                                     const GlobalTableFunctionState *global_state) -> double {
 		auto &gstate = global_state->Cast<ScanGlobalState>();
-		return 100.0 * (static_cast<double>(gstate.partitons_processed) / static_cast<double>(gstate.partitons_total));
+		return 100.0 * (static_cast<double>(gstate.partitions_processed) / static_cast<double>(gstate.partitons_total));
 	};
 
 	vortex_scan.pushdown_complex_filter = PushdownComplexFilter;
diff --git a/vortex-ffi/cinclude/vortex.h b/vortex-ffi/cinclude/vortex.h
index 7b45cb448fe..866275708b5 100644
--- a/vortex-ffi/cinclude/vortex.h
+++ b/vortex-ffi/cinclude/vortex.h
@@ -97,7 +97,7 @@ typedef struct vx_array vx_array;
 /**
  * The FFI interface for an [`ArrayIterator`].
  */
-typedef struct vx_array_iter vx_array_iter;
+typedef struct vx_array_iterator vx_array_iterator;
 
 /**
  * The `sink` interface is used to collect array chunks and place them into a resource
@@ -202,10 +202,10 @@ typedef struct vx_file_scan_options {
  *
  * It is an error to call this function again after the iterator is finished.
  */
-struct vx_array *vx_array_iter_next(struct vx_array_iter *iter,
+struct vx_array *vx_array_iter_next(struct vx_array_iterator *iter,
                                     struct vx_error **error);
 
-void vx_array_iter_free(struct vx_array_iter *array_iter);
+void vx_array_iter_free(struct vx_array_iterator *array_iter);
 
 /**
  * Get the length of the array.
@@ -395,11 +395,11 @@ void vx_file_statistics_free(struct vx_file_statistics *stat);
 struct vx_dtype *vx_file_dtype(const struct vx_file_reader *file);
 
 /**
- * Build a new `vx_array_iter` that returns a series of `vx_array`s from a scan over a `vx_layout_reader`.
+ * Build a new `vx_array_iterator` that returns a series of `vx_array`s from a scan over a `vx_layout_reader`.
  */
-struct vx_array_iter *vx_layout_reader_scan(const struct vx_layout_reader *layout_reader,
-                                            const struct vx_file_scan_options *opts,
-                                            struct vx_error **error);
+struct vx_array_iterator *vx_layout_reader_scan(const struct vx_layout_reader *layout_reader,
+                                                const struct vx_file_scan_options *opts,
+                                                struct vx_error **error);
 
 /**
  * Returns the row count for a given file reader.
@@ -417,7 +417,7 @@ void vx_layout_reader_free(struct vx_layout_reader *layout_reader);
 /**
  * Free the file and all associated resources.
  *
- * This function will not automatically free any :c:func:`vx_array_iter` that were built from
+ * This function will not automatically free any :c:func:`vx_array_iterator` that were built from
  * this file.
  */
 void vx_file_reader_free(struct vx_file_reader *file);
diff --git a/vortex-ffi/src/array.rs b/vortex-ffi/src/array.rs
index cbf91b1e905..bdff0a12416 100644
--- a/vortex-ffi/src/array.rs
+++ b/vortex-ffi/src/array.rs
@@ -25,17 +25,17 @@ pub struct vx_array {
 
 /// The FFI interface for an [`ArrayIterator`].
 #[allow(non_camel_case_types)]
-pub struct vx_array_iter {
+pub struct vx_array_iterator {
     pub inner: Option<Box<dyn ArrayIterator>>,
 }
 
 /// Creates a new ArrayIterator wrapper for FFI use.
-pub fn vx_array_iter<I>(iter: I) -> vortex::error::VortexResult<*mut vx_array_iter>
+pub fn vx_array_iterator<I>(iter: I) -> vortex::error::VortexResult<*mut vx_array_iterator>
 where
     I: ArrayIterator + 'static,
 {
     let inner = Some(Box::new(iter) as Box<dyn ArrayIterator>);
-    Ok(Box::into_raw(Box::new(vx_array_iter { inner })))
+    Ok(Box::into_raw(Box::new(vx_array_iterator { inner })))
 }
 
 /// Attempt to advance the `current` pointer of the iterator.
@@ -46,7 +46,7 @@ where
 /// It is an error to call this function again after the iterator is finished.
 #[unsafe(no_mangle)]
 pub unsafe extern "C-unwind" fn vx_array_iter_next(
-    iter: *mut vx_array_iter,
+    iter: *mut vx_array_iterator,
     error: *mut *mut vx_error,
 ) -> *mut vx_array {
     try_or(error, ptr::null_mut(), || {
@@ -68,7 +68,7 @@ pub unsafe extern "C-unwind" fn vx_array_iter_next(
 }
 
 #[unsafe(no_mangle)]
-pub unsafe extern "C-unwind" fn vx_array_iter_free(array_iter: *mut vx_array_iter) {
+pub unsafe extern "C-unwind" fn vx_array_iter_free(array_iter: *mut vx_array_iterator) {
     assert!(!array_iter.is_null());
     drop(unsafe { Box::from_raw(array_iter) });
 }
diff --git a/vortex-ffi/src/file.rs b/vortex-ffi/src/file.rs
index 0dd984736fe..616086df256 100644
--- a/vortex-ffi/src/file.rs
+++ b/vortex-ffi/src/file.rs
@@ -24,7 +24,7 @@ use vortex::layout::LayoutReader;
 use vortex::layout::scan::ScanBuilder;
 use vortex::proto::expr::Expr;
 
-use crate::array::{vx_array, vx_array_iter};
+use crate::array::{vx_array, vx_array_iterator};
 use crate::error::{try_or, vx_error};
 use crate::{RUNTIME, to_string, to_string_vec};
 
@@ -218,13 +218,13 @@ pub unsafe extern "C-unwind" fn vx_file_dtype(file: *const vx_file_reader) -> *m
     ))
 }
 
-/// Build a new `vx_array_iter` that returns a series of `vx_array`s from a scan over a `vx_layout_reader`.
+/// Build a new `vx_array_iterator` that returns a series of `vx_array`s from a scan over a `vx_layout_reader`.
 #[unsafe(no_mangle)]
 pub unsafe extern "C-unwind" fn vx_layout_reader_scan(
     layout_reader: *const vx_layout_reader,
     opts: *const vx_file_scan_options,
     error: *mut *mut vx_error,
-) -> *mut vx_array_iter {
+) -> *mut vx_array_iterator {
     try_or(error, ptr::null_mut(), || {
         let layout_reader = unsafe { layout_reader.as_ref().vortex_expect("null layout reader") };
         let mut scan_builder = ScanBuilder::new(layout_reader.inner.clone());
@@ -252,7 +252,7 @@ pub unsafe extern "C-unwind" fn vx_layout_reader_scan(
             scan_builder = scan_builder.with_split_by(split_by_value);
         }
 
-        vx_array_iter(scan_builder.into_array_iter()?)
+        vx_array_iterator(scan_builder.into_array_iter()?)
     })
 }
 
@@ -291,7 +291,7 @@ pub extern "C-unwind" fn vx_layout_reader_free(layout_reader: *mut vx_layout_rea
 
 /// Free the file and all associated resources.
 ///
-/// This function will not automatically free any :c:func:`vx_array_iter` that were built from
+/// This function will not automatically free any :c:func:`vx_array_iterator` that were built from
 /// this file.
 #[unsafe(no_mangle)]
 pub unsafe extern "C-unwind" fn vx_file_reader_free(file: *mut vx_file_reader) {


Reviews:
user: login: joseph-isaacs
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T13:28:12Z
user: login: 0ax1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T13:33:36Z
user: login: joseph-isaacs
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T13:41:53Z
user: login: 0ax1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T16:27:16Z
user: login: 0ax1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T16:34:04Z
user: login: 0ax1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T16:37:59Z
user: login: joseph-isaacs
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T09:21:32Z
user: login: joseph-isaacs
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T09:23:18Z
user: login: joseph-isaacs
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T09:24:12Z
user: login: 0ax1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T09:46:52Z

Review comments:
diff_hunk: @@ -20,7 +20,7 @@ template <typename Func>
 auto Try(Func func) {
 	vx_error *error = nullptr;
 	// Handle both void and non-void return types.
-	if constexpr (std::is_void_v<std::invoke_result_t<Func, vx_error**>>) {
+	if constexpr (std::is_void_v<std::invoke_result_t<Func, vx_error **>>) {
path: duckdb-vortex/src/include/vortex_error.hpp
user: login: joseph-isaacs
body: 🙈 
created_at: 2025-05-19T13:28:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -231,6 +239,12 @@ static unique_ptr<FileReader> OpenFileAndVerify(FileSystem &fs, const std::strin
 	return file;
 }
 
+static bool PinFileToThread(ScanGlobalState &global_state) {
+	const auto thread_count = std::thread::hardware_concurrency();
+	const auto file_count = global_state.expanded_files.size();
+	return (file_count - global_state.files_partitioned) > thread_count;
+}
path: duckdb-vortex/src/vortex_scan.cpp
user: login: joseph-isaacs
body: `thread_count` is likely much larger than the number of threads working on this scan.  
created_at: 2025-05-19T13:30:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -20,7 +20,7 @@ template <typename Func>
 auto Try(Func func) {
 	vx_error *error = nullptr;
 	// Handle both void and non-void return types.
-	if constexpr (std::is_void_v<std::invoke_result_t<Func, vx_error**>>) {
+	if constexpr (std::is_void_v<std::invoke_result_t<Func, vx_error **>>) {
path: duckdb-vortex/src/include/vortex_error.hpp
user: login: 0ax1
body: 😅 
created_at: 2025-05-19T13:33:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -249,17 +263,26 @@ static void CreateScanPartitions(ClientContext &context, const BindData &bind, S
 	const auto partition_count = std::max(static_cast<uint64_t>(1), row_count / partition_size);
 	global_state.partitons_total += partition_count;
 
-	// Pin threads to files as long as there more files than threads left to process.
-	const bool pin_file_to_thread = (file_count - global_state.files_partitioned) > thread_count;
-	auto &partitions_queue = pin_file_to_thread ? local_state.scan_partitions : global_state.scan_partitions;
-
-	for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
-
-		partitions_queue.enqueue(ScanPartition {
-		    .file_idx = file_idx,
-		    .start_row = partition_idx * partition_size,
-		    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
-		});
+	if (PinFileToThread(global_state)) {
+		local_state.partition_idx = 0;
+		local_state.scan_partitions.clear();
+		local_state.thread_local_file_idx = file_idx;
+
+		for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+			local_state.scan_partitions.push_back(ScanPartition {
+			    .file_idx = file_idx,
+			    .start_row = partition_idx * partition_size,
+			    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
+			});
path: duckdb-vortex/src/vortex_scan.cpp
user: login: joseph-isaacs
body: if you extract the `ScanPartition` ctor I think it makes it easier to see that the decision here is where to put the partition, but that it is
created_at: 2025-05-19T13:33:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -313,16 +340,17 @@ static bool GetNextArray(ClientContext &context, const BindData &bind_data, Scan
 			}
 		}
 
-		global_state.partitons_processed += 1;
-		std::shared_ptr<LayoutReader> layout_reader = global_state.layout_readers[partition.file_idx];
+		auto layout_reader = global_state.layout_readers[partition.file_idx];
path: duckdb-vortex/src/vortex_scan.cpp
user: login: joseph-isaacs
body: Why is this thread safe?
created_at: 2025-05-19T13:41:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -313,16 +340,17 @@ static bool GetNextArray(ClientContext &context, const BindData &bind_data, Scan
 			}
 		}
 
-		global_state.partitons_processed += 1;
-		std::shared_ptr<LayoutReader> layout_reader = global_state.layout_readers[partition.file_idx];
+		auto layout_reader = global_state.layout_readers[partition.file_idx];
path: duckdb-vortex/src/vortex_scan.cpp
user: login: 0ax1
body: adding a comment
created_at: 2025-05-19T16:27:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -231,6 +239,12 @@ static unique_ptr<FileReader> OpenFileAndVerify(FileSystem &fs, const std::strin
 	return file;
 }
 
+static bool PinFileToThread(ScanGlobalState &global_state) {
+	const auto thread_count = std::thread::hardware_concurrency();
+	const auto file_count = global_state.expanded_files.size();
+	return (file_count - global_state.files_partitioned) > thread_count;
+}
path: duckdb-vortex/src/vortex_scan.cpp
user: login: 0ax1
body: As discussed offline, for now this is good enough as in an approximation that if wrong might be a small perf hit.
created_at: 2025-05-19T16:34:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -231,6 +239,12 @@ static unique_ptr<FileReader> OpenFileAndVerify(FileSystem &fs, const std::strin
 	return file;
 }
 
+static bool PinFileToThread(ScanGlobalState &global_state) {
+	const auto thread_count = std::thread::hardware_concurrency();
+	const auto file_count = global_state.expanded_files.size();
+	return (file_count - global_state.files_partitioned) > thread_count;
+}
path: duckdb-vortex/src/vortex_scan.cpp
user: login: 0ax1
body: Added a comment
created_at: 2025-05-19T16:37:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -249,20 +264,28 @@ static void CreateScanPartitions(ClientContext &context, const BindData &bind, S
 	const auto partition_count = std::max(static_cast<uint64_t>(1), row_count / partition_size);
 	global_state.partitons_total += partition_count;
 
-	// Pin threads to files as long as there more files than threads left to process.
-	const bool pin_file_to_thread = (file_count - global_state.files_partitioned) > thread_count;
-	auto &partitions_queue = pin_file_to_thread ? local_state.scan_partitions : global_state.scan_partitions;
-
-	for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+	if (PinFileToThread(global_state)) {
+		local_state.thread_local_file_idx = file_idx;
 
-		partitions_queue.enqueue(ScanPartition {
-		    .file_idx = file_idx,
-		    .start_row = partition_idx * partition_size,
-		    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
-		});
+		for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+			local_state.scan_partitions.push(ScanPartition {
+			    .file_idx = file_idx,
+			    .start_row = partition_idx * partition_size,
+			    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
+			});
+		}
+	} else {
+		for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+			global_state.scan_partitions.enqueue(ScanPartition {
+			    .file_idx = file_idx,
+			    .start_row = partition_idx * partition_size,
+			    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
+			});
path: duckdb-vortex/src/vortex_scan.cpp
user: login: joseph-isaacs
body: This would read must easier to read if you swap the if and the for
created_at: 2025-05-20T09:21:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -67,10 +69,14 @@ struct ScanPartition {
 /// parallelized by dividing it into ranges, each handled by a different scan.
 struct ScanLocalState : public LocalTableFunctionState {
 	idx_t array_row_offset;
-	unique_ptr<Array> currently_scanned_array;
+	unique_ptr<Array> scanned_array;
path: duckdb-vortex/src/vortex_scan.cpp
user: login: joseph-isaacs
body: ```suggestion
	unique_ptr<Array> current_array;
```
created_at: 2025-05-20T09:23:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -249,20 +264,28 @@ static void CreateScanPartitions(ClientContext &context, const BindData &bind, S
 	const auto partition_count = std::max(static_cast<uint64_t>(1), row_count / partition_size);
 	global_state.partitons_total += partition_count;
 
-	// Pin threads to files as long as there more files than threads left to process.
-	const bool pin_file_to_thread = (file_count - global_state.files_partitioned) > thread_count;
-	auto &partitions_queue = pin_file_to_thread ? local_state.scan_partitions : global_state.scan_partitions;
-
-	for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+	if (PinFileToThread(global_state)) {
+		local_state.thread_local_file_idx = file_idx;
 
-		partitions_queue.enqueue(ScanPartition {
-		    .file_idx = file_idx,
-		    .start_row = partition_idx * partition_size,
-		    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
-		});
+		for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+			local_state.scan_partitions.push(ScanPartition {
+			    .file_idx = file_idx,
+			    .start_row = partition_idx * partition_size,
+			    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
+			});
+		}
+	} else {
+		for (size_t partition_idx = 0; partition_idx < partition_count; ++partition_idx) {
+			global_state.scan_partitions.enqueue(ScanPartition {
+			    .file_idx = file_idx,
+			    .start_row = partition_idx * partition_size,
+			    .end_row = (partition_idx + 1) == partition_count ? row_count : (partition_idx + 1) * partition_size,
+			});
path: duckdb-vortex/src/vortex_scan.cpp
user: login: 0ax1
body: done
created_at: 2025-05-20T09:46:52Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-14T12:48:32Z
body: # Benchmarks: TPC-H on NVME
<details>
<summary>Table of Results</summary>

| name                                       |   PR 313d8fe5 |   base 14231fb6 |   ratio (PR/base) | unit   |
|:-------------------------------------------|--------------:|----------------:|------------------:|:-------|
| tpch_q01/DataFusion:arrow                  |      65575912 |     6.61827e+07 |          0.990832 | ns     |
| tpch_q02/DataFusion:arrow                  |      16516130 |     1.64753e+07 |          1.00248  | ns     |
| tpch_q03/DataFusion:arrow                  |      23825504 |     2.33856e+07 |          1.01881  | ns     |
| tpch_q04/DataFusion:arrow                  |      18964896 |     1.86835e+07 |          1.01506  | ns     |
| tpch_q05/DataFusion:arrow                  |      32511816 |     3.23639e+07 |          1.00457  | ns     |
| tpch_q06/DataFusion:arrow                  |       6019599 |     5.93703e+06 |          1.01391  | ns     |
| tpch_q07/DataFusion:arrow                  |      52623948 |     5.27704e+07 |          0.997226 | ns     |
| tpch_q08/DataFusion:arrow                  |      18840933 |     1.91996e+07 |          0.981321 | ns     |
| tpch_q09/DataFusion:arrow                  |      34252310 |     3.34929e+07 |          1.02267  | ns     |
| tpch_q10/DataFusion:arrow                  |      38410139 |     3.92397e+07 |          0.978858 | ns     |
| tpch_q11/DataFusion:arrow                  |       7996591 |     7.98241e+06 |          1.00178  | ns     |
| tpch_q12/DataFusion:arrow                  |      18198608 |     1.78325e+07 |          1.02053  | ns     |
| tpch_q13/DataFusion:arrow                  |      14111325 |     1.45904e+07 |          0.967166 | ns     |
| tpch_q14/DataFusion:arrow                  |       8621512 |     8.14554e+06 |          1.05843  | ns     |
| tpch_q15/DataFusion:arrow                  |      17736350 |     1.79552e+07 |          0.987813 | ns     |
| tpch_q16/DataFusion:arrow                  |      14797319 |     1.51559e+07 |          0.976338 | ns     |
| tpch_q17/DataFusion:arrow                  |      49757342 |     4.93315e+07 |          1.00863  | ns     |
| tpch_q18/DataFusion:arrow                  |     104727839 |     1.09363e+08 |          0.957615 | ns     |
| tpch_q19/DataFusion:arrow                  |      17073146 |     1.71247e+07 |          0.996987 | ns     |
| tpch_q20/DataFusion:arrow                  |      23953176 |     2.30989e+07 |          1.03698  | ns     |
| tpch_q21/DataFusion:arrow                  |      82771132 |     8.35439e+07 |          0.990751 | ns     |
| tpch_q22/DataFusion:arrow                  |      10565552 |     1.05292e+07 |          1.00345  | ns     |
| tpch_q01/DataFusion:parquet                |     102685707 |     1.02732e+08 |          0.999552 | ns     |
| tpch_q02/DataFusion:parquet                |      50607586 |     5.16191e+07 |          0.980404 | ns     |
| tpch_q03/DataFusion:parquet                |      46354854 |     4.8328e+07  |          0.959172 | ns     |
| tpch_q04/DataFusion:parquet                |      30461213 |     3.03922e+07 |          1.00227  | ns     |
| tpch_q05/DataFusion:parquet                |      63327532 |     6.46542e+07 |          0.979481 | ns     |
| tpch_q06/DataFusion:parquet                |      28931925 |     2.88379e+07 |          1.00326  | ns     |
| tpch_q07/DataFusion:parquet                |      80950578 |     8.05654e+07 |          1.00478  | ns     |
| tpch_q08/DataFusion:parquet                |      60271422 |     6.06206e+07 |          0.99424  | ns     |
| tpch_q09/DataFusion:parquet                |      85806329 |     8.60219e+07 |          0.997494 | ns     |
| tpch_q10/DataFusion:parquet                |      93114057 |     9.21695e+07 |          1.01025  | ns     |
| tpch_q11/DataFusion:parquet                |      29231708 |     2.91228e+07 |          1.00374  | ns     |
| tpch_q12/DataFusion:parquet                |      38916352 |     3.83202e+07 |          1.01556  | ns     |
| tpch_q13/DataFusion:parquet                |      43823128 |     4.37867e+07 |          1.00083  | ns     |
| tpch_q14/DataFusion:parquet                |      33014851 |     3.19113e+07 |          1.03458  | ns     |
| tpch_q15/DataFusion:parquet                |      55308695 |     5.36925e+07 |          1.0301   | ns     |
| tpch_q16/DataFusion:parquet                |      34852530 |     3.53221e+07 |          0.986706 | ns     |
| tpch_q17/DataFusion:parquet                |      93489780 |     9.71502e+07 |          0.962322 | ns     |
| tpch_q18/DataFusion:parquet                |     116922102 |     1.15623e+08 |          1.01124  | ns     |
| tpch_q19/DataFusion:parquet                |      72422736 |     7.20925e+07 |          1.00458  | ns     |
| tpch_q20/DataFusion:parquet                |      56645295 |     5.69053e+07 |          0.995432 | ns     |
| tpch_q21/DataFusion:parquet                |     102786374 |     1.01391e+08 |          1.01377  | ns     |
| tpch_q22/DataFusion:parquet                |      52628541 |     5.18132e+07 |          1.01574  | ns     |
| tpch_q01/DataFusion:vortex-file-compressed |      60047177 |     5.86909e+07 |          1.02311  | ns     |
| tpch_q02/DataFusion:vortex-file-compressed |      40143650 |     3.70406e+07 |          1.08377  | ns     |
| tpch_q03/DataFusion:vortex-file-compressed |      29474852 |     2.95478e+07 |          0.997533 | ns     |
| tpch_q04/DataFusion:vortex-file-compressed |      15845872 |     1.53599e+07 |          1.03164  | ns     |
| tpch_q05/DataFusion:vortex-file-compressed |      47433154 |     4.76453e+07 |          0.995548 | ns     |
| tpch_q06/DataFusion:vortex-file-compressed |       4176120 |     4.02587e+06 |          1.03732  | ns     |
| tpch_q07/DataFusion:vortex-file-compressed |      63961198 |     6.39741e+07 |          0.999798 | ns     |
| tpch_q08/DataFusion:vortex-file-compressed |      54361443 |     5.42798e+07 |          1.0015   | ns     |
| tpch_q09/DataFusion:vortex-file-compressed |      74239397 |     7.35797e+07 |          1.00897  | ns     |
| tpch_q10/DataFusion:vortex-file-compressed |      43581838 |     4.36792e+07 |          0.997771 | ns     |
| tpch_q11/DataFusion:vortex-file-compressed |      25530586 |     2.56626e+07 |          0.994857 | ns     |
| tpch_q12/DataFusion:vortex-file-compressed |      17154079 |     1.73365e+07 |          0.989479 | ns     |
| tpch_q13/DataFusion:vortex-file-compressed |      17752729 |     1.84135e+07 |          0.964113 | ns     |
| tpch_q14/DataFusion:vortex-file-compressed |       9558949 |     9.59828e+06 |          0.995903 | ns     |
| tpch_q15/DataFusion:vortex-file-compressed |      17546366 |     1.74477e+07 |          1.00565  | ns     |
| tpch_q16/DataFusion:vortex-file-compressed |      24123197 |     2.41042e+07 |          1.00079  | ns     |
| tpch_q17/DataFusion:vortex-file-compressed |      75375782 |     7.58117e+07 |          0.99425  | ns     |
| tpch_q18/DataFusion:vortex-file-compressed |      93773623 |     9.4839e+07  |          0.988767 | ns     |
| tpch_q19/DataFusion:vortex-file-compressed |      16681405 |     1.68611e+07 |          0.989344 | ns     |
| tpch_q20/DataFusion:vortex-file-compressed |      27269497 |     2.65469e+07 |          1.02722  | ns     |
| tpch_q21/DataFusion:vortex-file-compressed |      86582015 |     8.58381e+07 |          1.00867  | ns     |
| tpch_q22/DataFusion:vortex-file-compressed |      12612923 |     1.28406e+07 |          0.982273 | ns     |
| tpch_q01/DuckDB:parquet                    |      65000000 |     6.4e+07     |          1.01562  | ns     |
| tpch_q02/DuckDB:parquet                    |      36000000 |     3.6e+07     |          1        | ns     |
| tpch_q03/DuckDB:parquet                    |      80000000 |     7.9e+07     |          1.01266  | ns     |
| tpch_q04/DuckDB:parquet                    |      39000000 |     3.9e+07     |          1        | ns     |
| tpch_q05/DuckDB:parquet                    |      57000000 |     5.7e+07     |          1        | ns     |
| tpch_q06/DuckDB:parquet                    |      31000000 |     3.1e+07     |          1        | ns     |
| tpch_q07/DuckDB:parquet                    |      59000000 |     6.1e+07     |          0.967213 | ns     |
| tpch_q08/DuckDB:parquet                    |      68000000 |     6.9e+07     |          0.985507 | ns     |
| tpch_q09/DuckDB:parquet                    |      96000000 |     1e+08       |          0.96     | ns     |
| tpch_q10/DuckDB:parquet                    |     328000000 |     3.27e+08    |          1.00306  | ns     |
| tpch_q11/DuckDB:parquet                    |      19000000 |     1.8e+07     |          1.05556  | ns     |
| tpch_q12/DuckDB:parquet                    |      46000000 |     4.3e+07     |          1.06977  | ns     |
| tpch_q13/DuckDB:parquet                    |      55000000 |     5.3e+07     |          1.03774  | ns     |
| tpch_q14/DuckDB:parquet                    |      50000000 |     4.8e+07     |          1.04167  | ns     |
| tpch_q15/DuckDB:parquet                    |      64000000 |     6.3e+07     |          1.01587  | ns     |
| tpch_q16/DuckDB:parquet                    |      69000000 |     6.9e+07     |          1        | ns     |
| tpch_q17/DuckDB:parquet                    |      62000000 |     6.2e+07     |          1        | ns     |
| tpch_q18/DuckDB:parquet                    |      75000000 |     7.4e+07     |          1.01351  | ns     |
| tpch_q19/DuckDB:parquet                    |      69000000 |     7e+07       |          0.985714 | ns     |
| tpch_q20/DuckDB:parquet                    |      60000000 |     5.8e+07     |          1.03448  | ns     |
| tpch_q21/DuckDB:parquet                    |     120000000 |     1.15e+08    |          1.04348  | ns     |
| tpch_q22/DuckDB:parquet                    |      45000000 |     4.4e+07     |          1.02273  | ns     |
| tpch_q01/DuckDB:vortex-file-compressed     |      49000000 |     4.8e+07     |          1.02083  | ns     |
| tpch_q02/DuckDB:vortex-file-compressed     |      55000000 |     6.3e+07     |          0.873016 | ns     |
| tpch_q03/DuckDB:vortex-file-compressed     |      76000000 |     8.1e+07     |          0.938272 | ns     |
| tpch_q04/DuckDB:vortex-file-compressed     |      44000000 |     4.5e+07     |          0.977778 | ns     |
| tpch_q05/DuckDB:vortex-file-compressed     |      66000000 |     6.5e+07     |          1.01538  | ns     |
| tpch_q06/DuckDB:vortex-file-compressed     |      15000000 |     1.5e+07     |          1        | ns     |
| tpch_q07/DuckDB:vortex-file-compressed     |      60000000 |     6e+07       |          1        | ns     |
| tpch_q08/DuckDB:vortex-file-compressed     |      78000000 |     8.1e+07     |          0.962963 | ns     |
| tpch_q09/DuckDB:vortex-file-compressed     |     103000000 |     9.6e+07     |          1.07292  | ns     |
| tpch_q10/DuckDB:vortex-file-compressed     |     293000000 |     2.95e+08    |          0.99322  | ns     |
| tpch_q11/DuckDB:vortex-file-compressed     |      36000000 |     3.8e+07     |          0.947368 | ns     |
| tpch_q12/DuckDB:vortex-file-compressed     |      41000000 |     4.3e+07     |          0.953488 | ns     |
| tpch_q13/DuckDB:vortex-file-compressed     |      61000000 |     6.1e+07     |          1        | ns     |
| tpch_q14/DuckDB:vortex-file-compressed     |      33000000 |     3.1e+07     |          1.06452  | ns     |
| tpch_q15/DuckDB:vortex-file-compressed     |      48000000 |     5.1e+07     |          0.941176 | ns     |
| tpch_q16/DuckDB:vortex-file-compressed     |      76000000 |     8e+07       |          0.95     | ns     |
| tpch_q17/DuckDB:vortex-file-compressed     |      56000000 |     5.2e+07     |          1.07692  | ns     |
| tpch_q18/DuckDB:vortex-file-compressed     |      79000000 |     8.3e+07     |          0.951807 | ns     |
| tpch_q19/DuckDB:vortex-file-compressed     |      41000000 |     4.4e+07     |          0.931818 | ns     |
| tpch_q20/DuckDB:vortex-file-compressed     |      54000000 |     5e+07       |          1.08     | ns     |
| tpch_q21/DuckDB:vortex-file-compressed     |     131000000 |     1.32e+08    |          0.992424 | ns     |
| tpch_q22/DuckDB:vortex-file-compressed     |      49000000 |     5e+07       |          0.98     | ns     |
| tpch_q01/DuckDB:duckdb                     |      27000000 |     2.6e+07     |          1.03846  | ns     |
| tpch_q02/DuckDB:duckdb                     |      22000000 |     2.1e+07     |          1.04762  | ns     |
| tpch_q03/DuckDB:duckdb                     |      54000000 |     5.4e+07     |          1        | ns     |
| tpch_q04/DuckDB:duckdb                     |      23000000 |     2.3e+07     |          1        | ns     |
| tpch_q05/DuckDB:duckdb                     |      32000000 |     3.2e+07     |          1        | ns     |
| tpch_q06/DuckDB:duckdb                     |      10000000 |     1e+07       |          1        | ns     |
| tpch_q07/DuckDB:duckdb                     |      33000000 |     3.3e+07     |          1        | ns     |
| tpch_q08/DuckDB:duckdb                     |      31000000 |     3.2e+07     |          0.96875  | ns     |
| tpch_q09/DuckDB:duckdb                     |      67000000 |     6.6e+07     |          1.01515  | ns     |
| tpch_q10/DuckDB:duckdb                     |     285000000 |     2.88e+08    |          0.989583 | ns     |
| tpch_q11/DuckDB:duckdb                     |      11000000 |     1.1e+07     |          1        | ns     |
| tpch_q12/DuckDB:duckdb                     |      29000000 |     2.9e+07     |          1        | ns     |
| tpch_q13/DuckDB:duckdb                     |      42000000 |     4.1e+07     |          1.02439  | ns     |
| tpch_q14/DuckDB:duckdb                     |      30000000 |     2.9e+07     |          1.03448  | ns     |
| tpch_q15/DuckDB:duckdb                     |      35000000 |     3.9e+07     |          0.897436 | ns     |
| tpch_q16/DuckDB:duckdb                     |      59000000 |     5.8e+07     |          1.01724  | ns     |
| tpch_q17/DuckDB:duckdb                     |      30000000 |     3e+07       |          1        | ns     |
| tpch_q18/DuckDB:duckdb                     |      47000000 |     4.6e+07     |          1.02174  | ns     |
| tpch_q19/DuckDB:duckdb                     |      41000000 |     4.2e+07     |          0.97619  | ns     |
| tpch_q20/DuckDB:duckdb                     |      35000000 |     3.4e+07     |          1.02941  | ns     |
| tpch_q21/DuckDB:duckdb                     |      64000000 |     6.5e+07     |          0.984615 | ns     |
| tpch_q22/DuckDB:duckdb                     |      32000000 |     3.3e+07     |          0.969697 | ns     |
</details>

<!-- thollander/actions-comment-pull-request "bench-pr-comment-tpch-nvme" -->
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-14T12:50:08Z
body: # Benchmarks: TPC-H on S3
<details>
<summary>Table of Results</summary>

| name                                       |   PR 313d8fe5 |   base 14231fb6 |   ratio (PR/base) | unit   |
|:-------------------------------------------|--------------:|----------------:|------------------:|:-------|
| tpch_q01/DataFusion:parquet                |     222933411 |     2.20561e+08 |          1.01076  | ns     |
| tpch_q02/DataFusion:parquet                |     754461889 |     7.85527e+08 |          0.960453 | ns     |
| tpch_q03/DataFusion:parquet                |     415264219 |     3.91146e+08 |          1.06166  | ns     |
| tpch_q04/DataFusion:parquet                |     238494638 |     2.21085e+08 |          1.07875  | ns     |
| tpch_q05/DataFusion:parquet                |     556986381 |     5.74775e+08 |          0.969052 | ns     |
| tpch_q06/DataFusion:parquet                |     147337985 |     1.48838e+08 |          0.989925 | ns     |
| tpch_q07/DataFusion:parquet                |     524108983 |     5.09838e+08 |          1.02799  | ns     |
| tpch_q08/DataFusion:parquet                |     768105332 |     7.49489e+08 |          1.02484  | ns     |
| tpch_q09/DataFusion:parquet                |     632598868 |     6.31141e+08 |          1.00231  | ns     |
| tpch_q10/DataFusion:parquet                |     540534430 |     5.61877e+08 |          0.962016 | ns     |
| tpch_q11/DataFusion:parquet                |     479856573 |     5.05549e+08 |          0.949178 | ns     |
| tpch_q12/DataFusion:parquet                |     285590804 |     3.04135e+08 |          0.939026 | ns     |
| tpch_q13/DataFusion:parquet                |     215894819 |     2.10622e+08 |          1.02504  | ns     |
| tpch_q14/DataFusion:parquet                |     290788016 |     2.84973e+08 |          1.02041  | ns     |
| tpch_q15/DataFusion:parquet                |     406502885 |     4.12092e+08 |          0.986438 | ns     |
| tpch_q16/DataFusion:parquet                |     370848435 |     3.84767e+08 |          0.963827 | ns     |
| tpch_q17/DataFusion:parquet                |     518335337 |     5.36084e+08 |          0.966893 | ns     |
| tpch_q18/DataFusion:parquet                |     473582158 |     4.68881e+08 |          1.01003  | ns     |
| tpch_q19/DataFusion:parquet                |     386683786 |     3.92502e+08 |          0.985177 | ns     |
| tpch_q20/DataFusion:parquet                |     528551358 |     5.53646e+08 |          0.954674 | ns     |
| tpch_q21/DataFusion:parquet                |     753799142 |     7.53622e+08 |          1.00024  | ns     |
| tpch_q22/DataFusion:parquet                |     283737334 |     2.87956e+08 |          0.98535  | ns     |
| tpch_q01/DataFusion:vortex-file-compressed |     157595989 |     1.48844e+08 |          1.0588   | ns     |
| tpch_q02/DataFusion:vortex-file-compressed |     171969706 |     1.58635e+08 |          1.08406  | ns     |
| tpch_q03/DataFusion:vortex-file-compressed |     247109912 |     2.432e+08   |          1.01608  | ns     |
| tpch_q04/DataFusion:vortex-file-compressed |     162579113 |     1.62108e+08 |          1.00291  | ns     |
| tpch_q05/DataFusion:vortex-file-compressed |     278401630 |     2.72301e+08 |          1.0224   | ns     |
| tpch_q06/DataFusion:vortex-file-compressed |      11852820 |     1.00514e+07 |          1.17922  | ns     |
| tpch_q07/DataFusion:vortex-file-compressed |     248308192 |     2.53678e+08 |          0.978831 | ns     |
| tpch_q08/DataFusion:vortex-file-compressed |     323107789 |     3.21884e+08 |          1.0038   | ns     |
| tpch_q09/DataFusion:vortex-file-compressed |     321000689 |     3.34829e+08 |          0.9587   | ns     |
| tpch_q10/DataFusion:vortex-file-compressed |     292927945 |     2.93673e+08 |          0.997464 | ns     |
| tpch_q11/DataFusion:vortex-file-compressed |     136892543 |     1.4126e+08  |          0.969081 | ns     |
| tpch_q12/DataFusion:vortex-file-compressed |     186593397 |     2.03394e+08 |          0.917397 | ns     |
| tpch_q13/DataFusion:vortex-file-compressed |     141206401 |     1.34521e+08 |          1.0497   | ns     |
| tpch_q14/DataFusion:vortex-file-compressed |     141904972 |     1.40334e+08 |          1.0112   | ns     |
| tpch_q15/DataFusion:vortex-file-compressed |     211899494 |     2.1142e+08  |          1.00227  | ns     |
| tpch_q16/DataFusion:vortex-file-compressed |      97107703 |     9.77272e+07 |          0.993661 | ns     |
| tpch_q17/DataFusion:vortex-file-compressed |     260588027 |     2.75239e+08 |          0.946771 | ns     |
| tpch_q18/DataFusion:vortex-file-compressed |     303140539 |     3.10329e+08 |          0.976837 | ns     |
| tpch_q19/DataFusion:vortex-file-compressed |      52687551 |     4.61234e+07 |          1.14232  | ns     |
| tpch_q20/DataFusion:vortex-file-compressed |     223805159 |     2.08293e+08 |          1.07447  | ns     |
| tpch_q21/DataFusion:vortex-file-compressed |     379411759 |     3.76564e+08 |          1.00756  | ns     |
| tpch_q22/DataFusion:vortex-file-compressed |     109927569 |     1.18274e+08 |          0.929429 | ns     |
</details>

<!-- thollander/actions-comment-pull-request "bench-pr-comment-tpch-s3" -->
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-14T13:02:15Z
body: # Benchmarks: Clickbench on NVME
<details>
<summary>Table of Results</summary>

| name                                             |   PR 313d8fe5 |   base 14231fb6 |   ratio (PR/base) | unit   |
|:-------------------------------------------------|--------------:|----------------:|------------------:|:-------|
| clickbench_q00/DataFusion:parquet                |       1297655 |     1.31276e+06 |          0.988496 | ns     |
| clickbench_q01/DataFusion:parquet                |      27783824 |     2.73146e+07 |          1.01718  | ns     |
| clickbench_q02/DataFusion:parquet                |      65990108 |     6.32939e+07 |          1.0426   | ns     |
| clickbench_q03/DataFusion:parquet                |      52616787 |     5.37922e+07 |          0.97815  | ns     |
| clickbench_q04/DataFusion:parquet                |     401679462 |     3.96736e+08 |          1.01246  | ns     |
| clickbench_q05/DataFusion:parquet                |     383293878 |     3.73455e+08 |          1.02635  | ns     |
| clickbench_q06/DataFusion:parquet                |       1331965 |     1.36277e+06 |          0.977397 | ns     |
| clickbench_q07/DataFusion:parquet                |      30109237 |     3.00947e+07 |          1.00048  | ns     |
| clickbench_q08/DataFusion:parquet                |     458302086 |     4.53022e+08 |          1.01166  | ns     |
| clickbench_q09/DataFusion:parquet                |     674994225 |     6.80708e+08 |          0.991606 | ns     |
| clickbench_q10/DataFusion:parquet                |     147582323 |     1.45736e+08 |          1.01267  | ns     |
| clickbench_q11/DataFusion:parquet                |     176448156 |     1.73113e+08 |          1.01927  | ns     |
| clickbench_q12/DataFusion:parquet                |     409458370 |     4.02573e+08 |          1.0171   | ns     |
| clickbench_q13/DataFusion:parquet                |     577946389 |     5.69766e+08 |          1.01436  | ns     |
| clickbench_q14/DataFusion:parquet                |     394915856 |     3.84559e+08 |          1.02693  | ns     |
| clickbench_q15/DataFusion:parquet                |     462558261 |     4.58249e+08 |          1.0094   | ns     |
| clickbench_q16/DataFusion:parquet                |     824324051 |     8.02516e+08 |          1.02718  | ns     |
| clickbench_q17/DataFusion:parquet                |     800869852 |     7.78577e+08 |          1.02863  | ns     |
| clickbench_q18/DataFusion:parquet                |    1519256980 |     1.46122e+09 |          1.03972  | ns     |
| clickbench_q19/DataFusion:parquet                |      42062869 |     4.09482e+07 |          1.02722  | ns     |
| clickbench_q20/DataFusion:parquet                |     659246953 |     6.45861e+08 |          1.02073  | ns     |
| clickbench_q21/DataFusion:parquet                |     760762424 |     7.38075e+08 |          1.03074  | ns     |
| clickbench_q22/DataFusion:parquet                |    1198246792 |     1.17892e+09 |          1.01639  | ns     |
| clickbench_q23/DataFusion:parquet                |    4941613210 |     4.89787e+09 |          1.00893  | ns     |
| clickbench_q24/DataFusion:parquet                |     248520220 |     2.4395e+08  |          1.01873  | ns     |
| clickbench_q25/DataFusion:parquet                |     212807196 |     2.0765e+08  |          1.02483  | ns     |
| clickbench_q26/DataFusion:parquet                |     275240271 |     2.76142e+08 |          0.996735 | ns     |
| clickbench_q27/DataFusion:parquet                |     987778278 |     9.6554e+08  |          1.02303  | ns     |
| clickbench_q28/DataFusion:parquet                |    5825192604 |     5.77239e+09 |          1.00915  | ns     |
| clickbench_q29/DataFusion:parquet                |     235979029 |     2.41667e+08 |          0.976464 | ns     |
| clickbench_q30/DataFusion:parquet                |     390289641 |     3.83138e+08 |          1.01867  | ns     |
| clickbench_q31/DataFusion:parquet                |     437621488 |     4.34239e+08 |          1.00779  | ns     |
| clickbench_q32/DataFusion:parquet                |    1353842927 |     1.33846e+09 |          1.01149  | ns     |
| clickbench_q33/DataFusion:parquet                |    1703676245 |     1.67496e+09 |          1.01714  | ns     |
| clickbench_q34/DataFusion:parquet                |    1695827243 |     1.67334e+09 |          1.01344  | ns     |
| clickbench_q35/DataFusion:parquet                |     616811701 |     6.15884e+08 |          1.00151  | ns     |
| clickbench_q36/DataFusion:parquet                |     185424954 |     1.76996e+08 |          1.04762  | ns     |
| clickbench_q37/DataFusion:parquet                |      71582323 |     7.10027e+07 |          1.00816  | ns     |
| clickbench_q38/DataFusion:parquet                |     113843562 |     1.05315e+08 |          1.08098  | ns     |
| clickbench_q39/DataFusion:parquet                |     356309747 |     3.40086e+08 |          1.0477   | ns     |
| clickbench_q40/DataFusion:parquet                |      43283379 |     4.06557e+07 |          1.06463  | ns     |
| clickbench_q41/DataFusion:parquet                |      37710787 |     3.9985e+07  |          0.943124 | ns     |
| clickbench_q42/DataFusion:parquet                |      58431448 |     5.79273e+07 |          1.0087   | ns     |
| clickbench_q00/DataFusion:vortex-file-compressed |       1318965 |     1.28096e+06 |          1.02967  | ns     |
| clickbench_q01/DataFusion:vortex-file-compressed |       7489415 |     6.75905e+06 |          1.10806  | ns     |
| clickbench_q02/DataFusion:vortex-file-compressed |      24310970 |     2.59585e+07 |          0.936533 | ns     |
| clickbench_q03/DataFusion:vortex-file-compressed |      34140814 |     3.52723e+07 |          0.967922 | ns     |
| clickbench_q04/DataFusion:vortex-file-compressed |     327922467 |     3.25853e+08 |          1.00635  | ns     |
| clickbench_q05/DataFusion:vortex-file-compressed |     338040862 |     3.31522e+08 |          1.01966  | ns     |
| clickbench_q06/DataFusion:vortex-file-compressed |       1418304 |     1.36622e+06 |          1.03813  | ns     |
| clickbench_q07/DataFusion:vortex-file-compressed |      12380798 |     1.14424e+07 |          1.08201  | ns     |
| clickbench_q08/DataFusion:vortex-file-compressed |     396288018 |     3.75839e+08 |          1.05441  | ns     |
| clickbench_q09/DataFusion:vortex-file-compressed |     570607823 |     5.62824e+08 |          1.01383  | ns     |
| clickbench_q10/DataFusion:vortex-file-compressed |      73781909 |     7.11946e+07 |          1.03634  | ns     |
| clickbench_q11/DataFusion:vortex-file-compressed |      85246250 |     8.00466e+07 |          1.06496  | ns     |
| clickbench_q12/DataFusion:vortex-file-compressed |     286252600 |     2.97093e+08 |          0.963512 | ns     |
| clickbench_q13/DataFusion:vortex-file-compressed |     481165192 |     4.7252e+08  |          1.0183   | ns     |
| clickbench_q14/DataFusion:vortex-file-compressed |     285985384 |     2.65658e+08 |          1.07652  | ns     |
| clickbench_q15/DataFusion:vortex-file-compressed |     406810574 |     3.9669e+08  |          1.02551  | ns     |
| clickbench_q16/DataFusion:vortex-file-compressed |     838394206 |     8.21283e+08 |          1.02083  | ns     |
| clickbench_q17/DataFusion:vortex-file-compressed |     799221189 |     7.93892e+08 |          1.00671  | ns     |
| clickbench_q18/DataFusion:vortex-file-compressed |    1516731728 |     1.49888e+09 |          1.01191  | ns     |
| clickbench_q19/DataFusion:vortex-file-compressed |      14050897 |     1.36653e+07 |          1.02822  | ns     |
| clickbench_q20/DataFusion:vortex-file-compressed |     272996957 |     2.65295e+08 |          1.02903  | ns     |
| clickbench_q21/DataFusion:vortex-file-compressed |     334197646 |     3.24335e+08 |          1.03041  | ns     |
| clickbench_q22/DataFusion:vortex-file-compressed |     675749471 |     6.84323e+08 |          0.987472 | ns     |
| clickbench_q23/DataFusion:vortex-file-compressed |    2091471379 |     2.04665e+09 |          1.0219   | ns     |
| clickbench_q24/DataFusion:vortex-file-compressed |     129844986 |     1.24153e+08 |          1.04584  | ns     |
| clickbench_q25/DataFusion:vortex-file-compressed |     100892326 |     1.02378e+08 |          0.98549  | ns     |
| clickbench_q26/DataFusion:vortex-file-compressed |     157291024 |     1.59963e+08 |          0.983298 | ns     |
| clickbench_q27/DataFusion:vortex-file-compressed |     677414619 |     6.71441e+08 |          1.0089   | ns     |
| clickbench_q28/DataFusion:vortex-file-compressed |    6568467831 |     6.49805e+09 |          1.01084  | ns     |
| clickbench_q29/DataFusion:vortex-file-compressed |     231904072 |     2.46404e+08 |          0.941153 | ns     |
| clickbench_q30/DataFusion:vortex-file-compressed |     245077746 |     2.47216e+08 |          0.991352 | ns     |
| clickbench_q31/DataFusion:vortex-file-compressed |     284108838 |     2.74792e+08 |          1.03391  | ns     |
| clickbench_q32/DataFusion:vortex-file-compressed |    1297594651 |     1.25404e+09 |          1.03473  | ns     |
| clickbench_q33/DataFusion:vortex-file-compressed |    1534943877 |     1.53441e+09 |          1.00035  | ns     |
| clickbench_q34/DataFusion:vortex-file-compressed |    1538369117 |     1.51167e+09 |          1.01766  | ns     |
| clickbench_q35/DataFusion:vortex-file-compressed |     561913902 |     5.4452e+08  |          1.03194  | ns     |
| clickbench_q36/DataFusion:vortex-file-compressed |      90368545 |     9.74297e+07 |          0.927525 | ns     |
| clickbench_q37/DataFusion:vortex-file-compressed |      36663015 |     3.78311e+07 |          0.969125 | ns     |
| clickbench_q38/DataFusion:vortex-file-compressed |      27304068 |     2.76551e+07 |          0.987308 | ns     |
| clickbench_q39/DataFusion:vortex-file-compressed |     190604002 |     1.88878e+08 |          1.00914  | ns     |
| clickbench_q40/DataFusion:vortex-file-compressed |      17299501 |     1.67151e+07 |          1.03496  | ns     |
| clickbench_q41/DataFusion:vortex-file-compressed |      14872587 |     1.30359e+07 |          1.14089  | ns     |
| clickbench_q42/DataFusion:vortex-file-compressed |      35860996 |     3.6193e+07  |          0.990826 | ns     |
| clickbench_q00/DuckDB:parquet                    |     242000000 |     2.41e+08    |          1.00415  | ns     |
| clickbench_q01/DuckDB:parquet                    |     157000000 |     1.57e+08    |          1        | ns     |
| clickbench_q02/DuckDB:parquet                    |     185000000 |     1.84e+08    |          1.00543  | ns     |
| clickbench_q03/DuckDB:parquet                    |     183000000 |     1.81e+08    |          1.01105  | ns     |
| clickbench_q04/DuckDB:parquet                    |     299000000 |     2.96e+08    |          1.01014  | ns     |
| clickbench_q05/DuckDB:parquet                    |     329000000 |     3.28e+08    |          1.00305  | ns     |
| clickbench_q06/DuckDB:parquet                    |     173000000 |     1.71e+08    |          1.0117   | ns     |
| clickbench_q07/DuckDB:parquet                    |     165000000 |     1.65e+08    |          1        | ns     |
| clickbench_q08/DuckDB:parquet                    |     340000000 |     3.34e+08    |          1.01796  | ns     |
| clickbench_q09/DuckDB:parquet                    |     441000000 |     4.4e+08     |          1.00227  | ns     |
| clickbench_q10/DuckDB:parquet                    |     220000000 |     2.16e+08    |          1.01852  | ns     |
| clickbench_q11/DuckDB:parquet                    |     230000000 |     2.33e+08    |          0.987124 | ns     |
| clickbench_q12/DuckDB:parquet                    |     345000000 |     3.46e+08    |          0.99711  | ns     |
| clickbench_q13/DuckDB:parquet                    |     523000000 |     5.19e+08    |          1.00771  | ns     |
| clickbench_q14/DuckDB:parquet                    |     385000000 |     3.85e+08    |          1        | ns     |
| clickbench_q15/DuckDB:parquet                    |     318000000 |     3.11e+08    |          1.02251  | ns     |
| clickbench_q16/DuckDB:parquet                    |     661000000 |     6.53e+08    |          1.01225  | ns     |
| clickbench_q17/DuckDB:parquet                    |     576000000 |     5.74e+08    |          1.00348  | ns     |
| clickbench_q18/DuckDB:parquet                    |    1079000000 |     1.065e+09   |          1.01315  | ns     |
| clickbench_q19/DuckDB:parquet                    |     162000000 |     1.6e+08     |          1.0125   | ns     |
| clickbench_q20/DuckDB:parquet                    |     768000000 |     7.7e+08     |          0.997403 | ns     |
| clickbench_q21/DuckDB:parquet                    |     703000000 |     6.99e+08    |          1.00572  | ns     |
| clickbench_q22/DuckDB:parquet                    |    1156000000 |     1.164e+09   |          0.993127 | ns     |
| clickbench_q23/DuckDB:parquet                    |    2664000000 |     2.642e+09   |          1.00833  | ns     |
| clickbench_q24/DuckDB:parquet                    |     141000000 |     1.48e+08    |          0.952703 | ns     |
| clickbench_q25/DuckDB:parquet                    |     236000000 |     2.34e+08    |          1.00855  | ns     |
| clickbench_q26/DuckDB:parquet                    |     150000000 |     1.47e+08    |          1.02041  | ns     |
| clickbench_q27/DuckDB:parquet                    |     828000000 |     8.24e+08    |          1.00485  | ns     |
| clickbench_q28/DuckDB:parquet                    |    6021000000 |     5.964e+09   |          1.00956  | ns     |
| clickbench_q29/DuckDB:parquet                    |     173000000 |     1.8e+08     |          0.961111 | ns     |
| clickbench_q30/DuckDB:parquet                    |     416000000 |     4.09e+08    |          1.01711  | ns     |
| clickbench_q31/DuckDB:parquet                    |     467000000 |     4.66e+08    |          1.00215  | ns     |
| clickbench_q32/DuckDB:parquet                    |    1142000000 |     1.117e+09   |          1.02238  | ns     |
| clickbench_q33/DuckDB:parquet                    |    1318000000 |     1.283e+09   |          1.02728  | ns     |
| clickbench_q34/DuckDB:parquet                    |    1383000000 |     1.354e+09   |          1.02142  | ns     |
| clickbench_q35/DuckDB:parquet                    |     412000000 |     3.96e+08    |          1.0404   | ns     |
| clickbench_q36/DuckDB:parquet                    |     157000000 |     1.54e+08    |          1.01948  | ns     |
| clickbench_q37/DuckDB:parquet                    |     152000000 |     1.54e+08    |          0.987013 | ns     |
| clickbench_q38/DuckDB:parquet                    |     160000000 |     1.61e+08    |          0.993789 | ns     |
| clickbench_q39/DuckDB:parquet                    |     183000000 |     1.82e+08    |          1.00549  | ns     |
| clickbench_q40/DuckDB:parquet                    |     154000000 |     1.53e+08    |          1.00654  | ns     |
| clickbench_q41/DuckDB:parquet                    |     162000000 |     1.58e+08    |          1.02532  | ns     |
| clickbench_q42/DuckDB:parquet                    |     145000000 |     1.49e+08    |          0.973154 | ns     |
| clickbench_q00/DuckDB:vortex-file-compressed     |      27000000 |     2.6e+07     |          1.03846  | ns     |
| clickbench_q01/DuckDB:vortex-file-compressed     |      39000000 |     3.2e+07     |          1.21875  | ns     |
| clickbench_q02/DuckDB:vortex-file-compressed     |     139000000 |     1.32e+08    |          1.05303  | ns     |
| clickbench_q03/DuckDB:vortex-file-compressed     |      96000000 |     9.2e+07     |          1.04348  | ns     |
| clickbench_q04/DuckDB:vortex-file-compressed     |     263000000 |     2.59e+08    |          1.01544  | ns     |
| clickbench_q05/DuckDB:vortex-file-compressed     |     298000000 |     3.01e+08    |          0.990033 | ns     |
| clickbench_q06/DuckDB:vortex-file-compressed     |      78000000 |     7.7e+07     |          1.01299  | ns     |
| clickbench_q07/DuckDB:vortex-file-compressed     |      47000000 |     4.6e+07     |          1.02174  | ns     |
| clickbench_q08/DuckDB:vortex-file-compressed     |     372000000 |     3.72e+08    |          1        | ns     |
| clickbench_q09/DuckDB:vortex-file-compressed     |     533000000 |     5.25e+08    |          1.01524  | ns     |
| clickbench_q10/DuckDB:vortex-file-compressed     |     141000000 |     1.24e+08    |          1.1371   | ns     |
| clickbench_q11/DuckDB:vortex-file-compressed     |     158000000 |     1.48e+08    |          1.06757  | ns     |
| clickbench_q12/DuckDB:vortex-file-compressed     |     273000000 |     2.73e+08    |          1        | ns     |
| clickbench_q13/DuckDB:vortex-file-compressed     |     486000000 |     4.62e+08    |          1.05195  | ns     |
| clickbench_q14/DuckDB:vortex-file-compressed     |     310000000 |     3.03e+08    |          1.0231   | ns     |
| clickbench_q15/DuckDB:vortex-file-compressed     |     292000000 |     2.77e+08    |          1.05415  | ns     |
| clickbench_q16/DuckDB:vortex-file-compressed     |     732000000 |     7.23e+08    |          1.01245  | ns     |
| clickbench_q17/DuckDB:vortex-file-compressed     |     662000000 |     6.44e+08    |          1.02795  | ns     |
| clickbench_q18/DuckDB:vortex-file-compressed     |    1332000000 |     1.33e+09    |          1.0015   | ns     |
| clickbench_q19/DuckDB:vortex-file-compressed     |     289000000 |     2.87e+08    |          1.00697  | ns     |
| clickbench_q20/DuckDB:vortex-file-compressed     |     475000000 |     4.42e+08    |          1.07466  | ns     |
| clickbench_q21/DuckDB:vortex-file-compressed     |     437000000 |     4.18e+08    |          1.04545  | ns     |
| clickbench_q22/DuckDB:vortex-file-compressed     |     686000000 |     6.51e+08    |          1.05376  | ns     |
| clickbench_q23/DuckDB:vortex-file-compressed     |    1874000000 |     1.795e+09   |          1.04401  | ns     |
| clickbench_q24/DuckDB:vortex-file-compressed     |     187000000 |     1.82e+08    |          1.02747  | ns     |
| clickbench_q25/DuckDB:vortex-file-compressed     |     140000000 |     1.41e+08    |          0.992908 | ns     |
| clickbench_q26/DuckDB:vortex-file-compressed     |     188000000 |     1.85e+08    |          1.01622  | ns     |
| clickbench_q27/DuckDB:vortex-file-compressed     |     667000000 |     6.65e+08    |          1.00301  | ns     |
| clickbench_q28/DuckDB:vortex-file-compressed     |    6536000000 |     6.352e+09   |          1.02897  | ns     |
| clickbench_q29/DuckDB:vortex-file-compressed     |     107000000 |     9.8e+07     |          1.09184  | ns     |
| clickbench_q30/DuckDB:vortex-file-compressed     |     276000000 |     2.72e+08    |          1.01471  | ns     |
| clickbench_q31/DuckDB:vortex-file-compressed     |     392000000 |     3.8e+08     |          1.03158  | ns     |
| clickbench_q32/DuckDB:vortex-file-compressed     |    1281000000 |     1.258e+09   |          1.01828  | ns     |
| clickbench_q33/DuckDB:vortex-file-compressed     |    1198000000 |     1.156e+09   |          1.03633  | ns     |
| clickbench_q34/DuckDB:vortex-file-compressed     |    1387000000 |     1.38e+09    |          1.00507  | ns     |
| clickbench_q35/DuckDB:vortex-file-compressed     |     450000000 |     4.43e+08    |          1.0158   | ns     |
| clickbench_q36/DuckDB:vortex-file-compressed     |      79000000 |     7.5e+07     |          1.05333  | ns     |
| clickbench_q37/DuckDB:vortex-file-compressed     |      59000000 |     5.9e+07     |          1        | ns     |
| clickbench_q38/DuckDB:vortex-file-compressed     |      69000000 |     7.1e+07     |          0.971831 | ns     |
| clickbench_q39/DuckDB:vortex-file-compressed     |     113000000 |     1.1e+08     |          1.02727  | ns     |
| clickbench_q40/DuckDB:vortex-file-compressed     |      50000000 |     4.8e+07     |          1.04167  | ns     |
| clickbench_q41/DuckDB:vortex-file-compressed     |      50000000 |     5e+07       |          1        | ns     |
| clickbench_q42/DuckDB:vortex-file-compressed     |      44000000 |     4.3e+07     |          1.02326  | ns     |
| clickbench_q00/DuckDB:duckdb                     |      18000000 |     1.8e+07     |          1        | ns     |
| clickbench_q01/DuckDB:duckdb                     |      37000000 |     3.6e+07     |          1.02778  | ns     |
| clickbench_q02/DuckDB:duckdb                     |      70000000 |     6.8e+07     |          1.02941  | ns     |
| clickbench_q03/DuckDB:duckdb                     |      63000000 |     6.3e+07     |          1        | ns     |
| clickbench_q04/DuckDB:duckdb                     |     237000000 |     2.3e+08     |          1.03043  | ns     |
| clickbench_q05/DuckDB:duckdb                     |     312000000 |     3.07e+08    |          1.01629  | ns     |
| clickbench_q06/DuckDB:duckdb                     |      40000000 |     4.1e+07     |          0.97561  | ns     |
| clickbench_q07/DuckDB:duckdb                     |      38000000 |     3.8e+07     |          1        | ns     |
| clickbench_q08/DuckDB:duckdb                     |     279000000 |     2.77e+08    |          1.00722  | ns     |
| clickbench_q09/DuckDB:duckdb                     |     384000000 |     3.81e+08    |          1.00787  | ns     |
| clickbench_q10/DuckDB:duckdb                     |     124000000 |     1.22e+08    |          1.01639  | ns     |
| clickbench_q11/DuckDB:duckdb                     |     138000000 |     1.36e+08    |          1.01471  | ns     |
| clickbench_q12/DuckDB:duckdb                     |     292000000 |     2.88e+08    |          1.01389  | ns     |
| clickbench_q13/DuckDB:duckdb                     |     468000000 |     4.63e+08    |          1.0108   | ns     |
| clickbench_q14/DuckDB:duckdb                     |     312000000 |     3.11e+08    |          1.00322  | ns     |
| clickbench_q15/DuckDB:duckdb                     |     258000000 |     2.58e+08    |          1        | ns     |
| clickbench_q16/DuckDB:duckdb                     |     625000000 |     6.21e+08    |          1.00644  | ns     |
| clickbench_q17/DuckDB:duckdb                     |     539000000 |     5.34e+08    |          1.00936  | ns     |
| clickbench_q18/DuckDB:duckdb                     |    1062000000 |     1.051e+09   |          1.01047  | ns     |
| clickbench_q19/DuckDB:duckdb                     |      35000000 |     3.6e+07     |          0.972222 | ns     |
| clickbench_q20/DuckDB:duckdb                     |     627000000 |     6.31e+08    |          0.993661 | ns     |
| clickbench_q21/DuckDB:duckdb                     |     524000000 |     5.26e+08    |          0.996198 | ns     |
| clickbench_q22/DuckDB:duckdb                     |     813000000 |     8.08e+08    |          1.00619  | ns     |
| clickbench_q23/DuckDB:duckdb                     |     326000000 |     3.24e+08    |          1.00617  | ns     |
| clickbench_q24/DuckDB:duckdb                     |      59000000 |     5.9e+07     |          1        | ns     |
| clickbench_q25/DuckDB:duckdb                     |     131000000 |     1.28e+08    |          1.02344  | ns     |
| clickbench_q26/DuckDB:duckdb                     |      57000000 |     5.8e+07     |          0.982759 | ns     |
| clickbench_q27/DuckDB:duckdb                     |     637000000 |     6.45e+08    |          0.987597 | ns     |
| clickbench_q28/DuckDB:duckdb                     |    5859000000 |     5.841e+09   |          1.00308  | ns     |
| clickbench_q29/DuckDB:duckdb                     |      59000000 |     5.9e+07     |          1        | ns     |
| clickbench_q30/DuckDB:duckdb                     |     315000000 |     3.05e+08    |          1.03279  | ns     |
| clickbench_q31/DuckDB:duckdb                     |     408000000 |     3.99e+08    |          1.02256  | ns     |
| clickbench_q32/DuckDB:duckdb                     |    1106000000 |     1.101e+09   |          1.00454  | ns     |
| clickbench_q33/DuckDB:duckdb                     |    1310000000 |     1.309e+09   |          1.00076  | ns     |
| clickbench_q34/DuckDB:duckdb                     |    1336000000 |     1.331e+09   |          1.00376  | ns     |
| clickbench_q35/DuckDB:duckdb                     |     322000000 |     3.03e+08    |          1.06271  | ns     |
| clickbench_q36/DuckDB:duckdb                     |      51000000 |     5.1e+07     |          1        | ns     |
| clickbench_q37/DuckDB:duckdb                     |      34000000 |     3.3e+07     |          1.0303   | ns     |
| clickbench_q38/DuckDB:duckdb                     |      34000000 |     3.4e+07     |          1        | ns     |
| clickbench_q39/DuckDB:duckdb                     |      70000000 |     6.9e+07     |          1.01449  | ns     |
| clickbench_q40/DuckDB:duckdb                     |      33000000 |     3.2e+07     |          1.03125  | ns     |
| clickbench_q41/DuckDB:duckdb                     |      34000000 |     3.4e+07     |          1        | ns     |
| clickbench_q42/DuckDB:duckdb                     |      32000000 |     3.2e+07     |          1        | ns     |
</details>

<!-- thollander/actions-comment-pull-request "bench-pr-comment-clickbench-nvme" -->
author_association: CONTRIBUTOR