From f286c452633f9fdd0c0e47a778955f5cf150c498 Mon Sep 17 00:00:00 2001 From: William Manley Date: Mon, 7 Aug 2023 16:55:56 +0100 Subject: [PATCH] Storage: Add Indexes for common queries In #306 it's reported that SQLite is slow. This adds indexes so lookups will be faster. The intention is to speed up the bottom 3 queries from https://github.com/github/stack-graphs/issues/306#issuecomment-1665402600 as they are "the ones to focus on". Specifically this should speed up: > * Load graph data for a file > > SELECT value FROM graphs WHERE file = ? > > Called many times during path stitching > > * Load paths for a file node > > SELECT file,value from file_paths WHERE file = ? AND local_id = ? > > Called many times during path stitching. > > * Load paths for root node > > SELECT file, value from root_paths WHERE symbol_stack = ? > > Called many times during path stitching. If the data that you're fetching is in the index then SQLite won't even bother reading the row proper, just pulling the data streight from the index (good for data locality). As such I've included not just the columns we're using in the `WHERE` clause, but also the ones from `SELECT` too. I've not actually tested the performance impact as I'm not familiar with this project (this is more of a drive-by) and don't know what benchmarks to use. --- stack-graphs/src/storage.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/stack-graphs/src/storage.rs b/stack-graphs/src/storage.rs index ee39c457e..6dcde928c 100644 --- a/stack-graphs/src/storage.rs +++ b/stack-graphs/src/storage.rs @@ -58,6 +58,12 @@ const SCHEMA: &str = r#" ) STRICT; "#; +const INDEXES: &str = r#" + CREATE INDEX IF NOT EXISTS graph_file_value ON graph(file, value); + CREATE INDEX IF NOT EXISTS file_paths_file_local_id_value ON file_paths(file, local_id, value); + CREATE INDEX IF NOT EXISTS root_paths_symbol_stack_file_value ON root_paths(symbol_stack, file, value); + "#; + const PRAGMAS: &str = r#" PRAGMA journal_mode = WAL; PRAGMA foreign_keys = false; @@ -161,6 +167,7 @@ impl SQLiteWriter { } else { check_version(&conn)?; } + Self::init_indexes(&mut conn)?; Ok(Self { conn }) } @@ -173,6 +180,13 @@ impl SQLiteWriter { Ok(()) } + fn init_indexes(conn: &mut Connection) -> Result<()> { + let tx = conn.transaction()?; + tx.execute_batch(INDEXES)?; + tx.commit()?; + Ok(()) + } + /// Clean all data from the database. pub fn clean_all(&mut self) -> Result { let tx = self.conn.transaction()?;