Skip to content

Commit 8a1e010

Browse files
sgrebnovlukekim
andauthored
DuckDB: include ANALYZE statement after write to update query optimizer statistics (#474)
* DuckDB: include ANALYZE statement after write to update query optimizer statistics. * Make execute_analyze_sql public Signed-off-by: Sergei Grebnov <sergei.grebnov@gmail.com> --------- Signed-off-by: Sergei Grebnov <sergei.grebnov@gmail.com> Co-authored-by: Luke Kim <80174+lukekim@users.noreply.github.com>
1 parent 8af9446 commit 8a1e010

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

core/src/duckdb/write.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,8 @@ fn insert_append(
466466
callback(&tx, &append_table, &schema, num_rows)?;
467467
}
468468

469+
execute_analyze_sql(&tx, &append_table.table_name().to_string());
470+
469471
on_commit_transaction
470472
.try_recv()
471473
.map_err(to_retriable_data_write_error)?;
@@ -640,6 +642,8 @@ fn insert_overwrite(
640642
callback(&tx, &new_table, &schema, num_rows)?;
641643
}
642644

645+
execute_analyze_sql(&tx, &new_table.table_name().to_string());
646+
643647
tx.commit()
644648
.context(super::UnableToCommitTransactionSnafu)
645649
.map_err(to_retriable_data_write_error)?;
@@ -707,6 +711,30 @@ fn write_to_table(
707711
Ok(rows as u64)
708712
}
709713

714+
/// Executes an ANALYZE statement to update query optimizer statistics.
715+
/// This helps DuckDB's query planner generate better execution plans, especially after large data changes.
716+
/// https://duckdb.org/docs/stable/sql/statements/analyze
717+
///
718+
/// Errors are logged but do not fail the operation since statistics updates are non-critical.
719+
pub fn execute_analyze_sql(tx: &Transaction, table_name: &str) {
720+
// DuckDB doesn't support parameterized table names in the ANALYZE statement
721+
let analyze_sql = format!(r#"ANALYZE "{}""#, table_name);
722+
tracing::debug!("Executing analyze SQL: {analyze_sql}");
723+
match tx.prepare(&analyze_sql) {
724+
Ok(mut stmt) => match stmt.execute([]) {
725+
Ok(_) => {
726+
tracing::debug!("Analyze SQL executed for table '{table_name}'");
727+
}
728+
Err(e) => {
729+
tracing::error!("Failed to execute analyze SQL for table '{table_name}': {e}");
730+
}
731+
},
732+
Err(e) => {
733+
tracing::error!("Failed to prepare analyze SQL for table '{table_name}': {e}");
734+
}
735+
}
736+
}
737+
710738
struct RecordBatchReaderFromStream {
711739
stream: Receiver<RecordBatch>,
712740
schema: SchemaRef,

0 commit comments

Comments
 (0)