# Process Each CSV File
for i, file in enumerate(csv_files, start=1):
file_start_time = time.time()
# Print progress message
print(f"Processing file {i}/{total_files}: {file}")
# Copy csv file to table
query = f"COPY search_data FROM '{file}'"
con.execute(query)
# cleanup
if i % batch_size == 0:
con.close() # Disconnect from DuckDB
gc.collect() # Force memory cleanup
con = duckdb.connect(raw_duckdb_path)
我发布了我发现的东西,而我的解决方法对此进行了几天,以防将来有人遇到这个问题。
我发现的主要解决方案是将大量CSV结合在一起,然后立即将其写入表。这是插入时已知的开销的精神。 我进行了速度测试,在其中我将200MB CSV的批量编号读入列表中,将它们组合在一起,将它们作为大型组合CSV写回磁盘,然后将其导入到我的DuckDB表中。我通过python进行了使用插入和复制的速度测试速度。I测试的批量大小为1、5、25、50、100、250和500 CSV。请注意,批处理大小为500,其CSV为〜100GB。作为参考,我正在运行一个使用512GB RAM,24 CPU的工作站,而IO的所有功能都使用M2 NVME SSD。 CSV有44列不同类型的列(字符串,整数,日期,双等),每个列有大约600-700K行。 速度反映了整个操作。 (连接到DB,阅读和组合CSV,插入 /复制以及断开连接)。以下是代码片段。
for batch_size in batch_sizes:
print(f"Processing batch size: {batch_size}")
# Start timing
start_time = time.time()
# Connect to DuckDB
con = duckdb.connect(raw_duckdb_path)
# Read CSVs into a list of DataFrames (up to batch_size files)
df_list = [pl.read_csv(csv) for csv in csv_files[:min(batch_size, total_files)]]
# Combine all DataFrames into one
combined_df = pl.concat(df_list, how="diagonal")
# Define output CSV path
output_path = f"{output_folder}/combined_{batch_size}.csv"
# Write the combined data to CSV
combined_df.write_csv(output_path)
# Insert CSV into DuckDB
#sql = f"INSERT INTO search_buying SELECT * FROM read_csv_auto('{output_path}');"
sql = f"COPY search_buying FROM '{output_path}' (AUTO_DETECT TRUE);"
con.execute(sql)
# Disconnect from DuckDB
con.close()
# End timing
elapsed_time = time.time() - start_time
# Compute implied time per CSV
time_per_csv = elapsed_time / batch_size
# Store results
results.append({"batch_size": batch_size, "time_taken": elapsed_time, "time_per_csv": time_per_csv})
在下面以及表格中绘制了recresults。
使用100批次和使用插入物优化了性能。 100个CSV的批次会导致大约20GB的组合文件,我怀疑大多数机器在RAM方面也更易于管理。我怀疑高速下降的速度实际上是来自组合CSV的更长的写入时间,而不是插入/副本,但我尚未对其进行测试。这些经过在一张已经进口的CSV约500GB的表上进行了测试,以确保它们不会在桌子变大的情况下展示我之前讨论的类似类型的慢速下降。虽然由于带有更大桌子的开销,它可能会变慢,但它基本上将在更多的CSV中拆分。
我仅使用插入物中的R中尝试了类似的东西,而时代很糟糕。要插入1 CSV花费4分钟,即使在每CSV大约30秒的100 csvs中,即使是在100 csvs中。我还发现在R中脱节正在花费很长时间,并且似乎存在重大泄漏的RAM问题。我认为我的duckdb库安装 /版本可能是一个问题。