Skip to content

Commit

Permalink
Add and improve sqlite describe performance benchmarks (launchbadge#2467
Browse files Browse the repository at this point in the history
)

* add basic describe benchmarks

* separate memory from query state

* move branch tracking & deduplication logic into a dedicated BranchList class

* Convert to using IntMap

* move intmap to a separate module, drop dead code, clean up function names

* Update Cargo.lock

* skip branches to check foreign keys, as they generally shouldn't impact query result type
  • Loading branch information
tyrelr authored May 8, 2023
1 parent 1227d5d commit 0dfebb2
Show file tree
Hide file tree
Showing 6 changed files with 611 additions and 242 deletions.
147 changes: 147 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ rand = "0.8.4"
rand_xoshiro = "0.6.0"
hex = "0.4.3"
tempdir = "0.3.7"
criterion = {version = "0.4", features = ["async_tokio"]}

# Needed to test SQLCipher
libsqlite3-sys = { version = "0.25.1", features = ["bundled-sqlcipher"] }

Expand Down Expand Up @@ -250,6 +252,12 @@ name = "sqlite-migrate"
path = "tests/sqlite/migrate.rs"
required-features = ["sqlite", "macros", "migrate"]

[[bench]]
name = "sqlite-describe"
path = "benches/sqlite/describe.rs"
harness = false
required-features = ["sqlite"]

#
# MySQL
#
Expand Down Expand Up @@ -332,3 +340,4 @@ required-features = ["postgres", "macros", "migrate"]
name = "postgres-migrate"
path = "tests/postgres/migrate.rs"
required-features = ["postgres", "macros", "migrate"]

141 changes: 141 additions & 0 deletions benches/sqlite/describe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};

use sqlx::sqlite::{Sqlite, SqliteConnection};
use sqlx::{Connection, Executor};
use sqlx_test::new;

// Here we have an async function to benchmark
async fn do_describe_trivial(db: &std::cell::RefCell<SqliteConnection>) {
db.borrow_mut().describe("select 1").await.unwrap();
}

async fn do_describe_recursive(db: &std::cell::RefCell<SqliteConnection>) {
db.borrow_mut()
.describe(
r#"
WITH RECURSIVE schedule(begin_date) AS MATERIALIZED (
SELECT datetime('2022-10-01')
WHERE datetime('2022-10-01') < datetime('2022-11-03')
UNION ALL
SELECT datetime(begin_date,'+1 day')
FROM schedule
WHERE datetime(begin_date) < datetime(?2)
)
SELECT
begin_date
FROM schedule
GROUP BY begin_date
"#,
)
.await
.unwrap();
}

async fn do_describe_insert(db: &std::cell::RefCell<SqliteConnection>) {
db.borrow_mut()
.describe("INSERT INTO tweet (id, text) VALUES (2, 'Hello') RETURNING *")
.await
.unwrap();
}

async fn do_describe_insert_fks(db: &std::cell::RefCell<SqliteConnection>) {
db.borrow_mut()
.describe("insert into statements (text) values ('a') returning id")
.await
.unwrap();
}

async fn init_connection() -> SqliteConnection {
let mut conn = new::<Sqlite>().await.unwrap();

conn.execute(
r#"
CREATE TEMPORARY TABLE statements (
id integer not null primary key,
text text not null
);
CREATE TEMPORARY TABLE votes1 (statement_id integer not null references statements(id));
CREATE TEMPORARY TABLE votes2 (statement_id integer not null references statements(id));
CREATE TEMPORARY TABLE votes3 (statement_id integer not null references statements(id));
CREATE TEMPORARY TABLE votes4 (statement_id integer not null references statements(id));
CREATE TEMPORARY TABLE votes5 (statement_id integer not null references statements(id));
CREATE TEMPORARY TABLE votes6 (statement_id integer not null references statements(id));
--CREATE TEMPORARY TABLE votes7 (statement_id integer not null references statements(id));
--CREATE TEMPORARY TABLE votes8 (statement_id integer not null references statements(id));
--CREATE TEMPORARY TABLE votes9 (statement_id integer not null references statements(id));
--CREATE TEMPORARY TABLE votes10 (statement_id integer not null references statements(id));
--CREATE TEMPORARY TABLE votes11 (statement_id integer not null references statements(id));
"#,
)
.await
.unwrap();
conn
}

fn describe_trivial(c: &mut Criterion) {
let runtime = tokio::runtime::Runtime::new().unwrap();
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));

c.bench_with_input(
BenchmarkId::new("select", "trivial"),
&db,
move |b, db_ref| {
// Insert a call to `to_async` to convert the bencher to async mode.
// The timing loops are the same as with the normal bencher.
b.to_async(&runtime).iter(|| do_describe_trivial(db_ref));
},
);
}

fn describe_recursive(c: &mut Criterion) {
let runtime = tokio::runtime::Runtime::new().unwrap();
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));

c.bench_with_input(
BenchmarkId::new("select", "recursive"),
&db,
move |b, db_ref| {
// Insert a call to `to_async` to convert the bencher to async mode.
// The timing loops are the same as with the normal bencher.
b.to_async(&runtime).iter(|| do_describe_recursive(db_ref));
},
);
}

fn describe_insert(c: &mut Criterion) {
let runtime = tokio::runtime::Runtime::new().unwrap();
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));

c.bench_with_input(
BenchmarkId::new("insert", "returning"),
&db,
move |b, db_ref| {
// Insert a call to `to_async` to convert the bencher to async mode.
// The timing loops are the same as with the normal bencher.
b.to_async(&runtime).iter(|| do_describe_insert(db_ref));
},
);
}

fn describe_insert_fks(c: &mut Criterion) {
let runtime = tokio::runtime::Runtime::new().unwrap();
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));

c.bench_with_input(BenchmarkId::new("insert", "fks"), &db, move |b, db_ref| {
// Insert a call to `to_async` to convert the bencher to async mode.
// The timing loops are the same as with the normal bencher.
b.to_async(&runtime).iter(|| do_describe_insert_fks(db_ref));
});
}

criterion_group!(
benches,
describe_trivial,
describe_recursive,
describe_insert,
describe_insert_fks
);
criterion_main!(benches);
Loading

0 comments on commit 0dfebb2

Please sign in to comment.