mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 15:25:32 +00:00
[SQLite] Add option to execute PRAGMA optimize;
on close of a connection (#2116)
* CHANGELOG: mention that users should upgrade CLI * [SQLite] Add option to execute `PRAGMA optimize;` on close of a connection * Update sqlx-sqlite/src/options/mod.rs * Update sqlx-sqlite/src/options/mod.rs * Update sqlx-sqlite/src/options/mod.rs --------- Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
This commit is contained in:
parent
ab2ae26189
commit
1fd05716af
@ -11,8 +11,11 @@ use std::ptr::NonNull;
|
||||
|
||||
use crate::connection::establish::EstablishParams;
|
||||
use crate::connection::worker::ConnectionWorker;
|
||||
use crate::options::OptimizeOnClose;
|
||||
use crate::statement::VirtualStatement;
|
||||
use crate::{Sqlite, SqliteConnectOptions};
|
||||
use sqlx_core::executor::Executor;
|
||||
use std::fmt::Write;
|
||||
|
||||
pub(crate) use sqlx_core::connection::*;
|
||||
|
||||
@ -39,6 +42,7 @@ mod worker;
|
||||
/// You can explicitly call [`.close()`][Self::close] to ensure the database is closed successfully
|
||||
/// or get an error otherwise.
|
||||
pub struct SqliteConnection {
|
||||
optimize_on_close: OptimizeOnClose,
|
||||
pub(crate) worker: ConnectionWorker,
|
||||
pub(crate) row_channel_size: usize,
|
||||
}
|
||||
@ -70,6 +74,7 @@ impl SqliteConnection {
|
||||
let params = EstablishParams::from_options(options)?;
|
||||
let worker = ConnectionWorker::establish(params).await?;
|
||||
Ok(Self {
|
||||
optimize_on_close: options.optimize_on_close.clone(),
|
||||
worker,
|
||||
row_channel_size: options.row_channel_size,
|
||||
})
|
||||
@ -102,6 +107,14 @@ impl Connection for SqliteConnection {
|
||||
|
||||
fn close(mut self) -> BoxFuture<'static, Result<(), Error>> {
|
||||
Box::pin(async move {
|
||||
if let OptimizeOnClose::Enabled { analysis_limit } = self.optimize_on_close {
|
||||
let mut pragma_string = String::new();
|
||||
if let Some(limit) = analysis_limit {
|
||||
write!(pragma_string, "PRAGMA analysis_limit = {}; ", limit).ok();
|
||||
}
|
||||
pragma_string.push_str("PRAGMA optimize;");
|
||||
self.execute(&*pragma_string).await?;
|
||||
}
|
||||
let shutdown = self.worker.shutdown();
|
||||
// Drop the statement worker, which should
|
||||
// cover all references to the connection handle outside of the worker thread
|
||||
|
@ -80,10 +80,18 @@ pub struct SqliteConnectOptions {
|
||||
pub(crate) serialized: bool,
|
||||
pub(crate) thread_name: Arc<DebugFn<dyn Fn(u64) -> String + Send + Sync + 'static>>,
|
||||
|
||||
pub(crate) optimize_on_close: OptimizeOnClose,
|
||||
|
||||
#[cfg(feature = "regexp")]
|
||||
pub(crate) register_regexp_function: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum OptimizeOnClose {
|
||||
Enabled { analysis_limit: Option<u32> },
|
||||
Disabled,
|
||||
}
|
||||
|
||||
impl Default for SqliteConnectOptions {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
@ -170,6 +178,9 @@ impl SqliteConnectOptions {
|
||||
|
||||
pragmas.insert("auto_vacuum".into(), None);
|
||||
|
||||
// Soft limit on the number of rows that `ANALYZE` touches per index.
|
||||
pragmas.insert("analysis_limit".into(), None);
|
||||
|
||||
Self {
|
||||
filename: Cow::Borrowed(Path::new(":memory:")),
|
||||
in_memory: false,
|
||||
@ -188,6 +199,7 @@ impl SqliteConnectOptions {
|
||||
thread_name: Arc::new(DebugFn(|id| format!("sqlx-sqlite-worker-{}", id))),
|
||||
command_channel_size: 50,
|
||||
row_channel_size: 50,
|
||||
optimize_on_close: OptimizeOnClose::Disabled,
|
||||
#[cfg(feature = "regexp")]
|
||||
register_regexp_function: false,
|
||||
}
|
||||
@ -464,6 +476,54 @@ impl SqliteConnectOptions {
|
||||
self
|
||||
}
|
||||
|
||||
/// Execute `PRAGMA optimize;` on the SQLite connection before closing.
|
||||
///
|
||||
/// The SQLite manual recommends using this for long-lived databases.
|
||||
///
|
||||
/// This will collect and store statistics about the layout of data in your tables to help the query planner make better decisions.
|
||||
/// Over the connection's lifetime, the query planner will make notes about which tables could use up-to-date statistics so this
|
||||
/// command doesn't have to scan the whole database every time. Thus, the best time to execute this is on connection close.
|
||||
///
|
||||
/// `analysis_limit` sets a soft limit on the maximum number of rows to scan per index.
|
||||
/// It is equivalent to setting [`Self::analysis_limit`] but only takes effect for the `PRAGMA optimize;` call
|
||||
/// and does not affect the behavior of any `ANALYZE` statements made during the connection's lifetime.
|
||||
///
|
||||
/// If not `None`, the `analysis_limit` here overrides the global `analysis_limit` setting,
|
||||
/// but only for the `PRAGMA optimize;` call.
|
||||
///
|
||||
/// Not enabled by default.
|
||||
///
|
||||
/// See [the SQLite manual](https://www.sqlite.org/lang_analyze.html#automatically_running_analyze) for details.
|
||||
pub fn optimize_on_close(
|
||||
mut self,
|
||||
enabled: bool,
|
||||
analysis_limit: impl Into<Option<u32>>,
|
||||
) -> Self {
|
||||
self.optimize_on_close = if enabled {
|
||||
OptimizeOnClose::Enabled {
|
||||
analysis_limit: (analysis_limit.into()),
|
||||
}
|
||||
} else {
|
||||
OptimizeOnClose::Disabled
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a soft limit on the number of rows that `ANALYZE` touches per index.
|
||||
///
|
||||
/// This also affects `PRAGMA optimize` which is set by [Self::optimize_on_close].
|
||||
///
|
||||
/// The value recommended by SQLite is `400`. There is no default.
|
||||
///
|
||||
/// See [the SQLite manual](https://www.sqlite.org/lang_analyze.html#approx) for details.
|
||||
pub fn analysis_limit(mut self, limit: impl Into<Option<u32>>) -> Self {
|
||||
if let Some(limit) = limit.into() {
|
||||
return self.pragma("analysis_limit", limit.to_string());
|
||||
}
|
||||
self.pragmas.insert("analysis_limit".into(), None);
|
||||
self
|
||||
}
|
||||
|
||||
/// Register a regexp function that allows using regular expressions in queries.
|
||||
///
|
||||
/// ```
|
||||
|
Loading…
x
Reference in New Issue
Block a user