From ff0ffff420df20b3f5d77c01dd24383a2f8cef36 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 26 Oct 2024 11:09:54 +0200 Subject: [PATCH] Add SQLite3 index on network_addresses(network_id) to speed up the client suggestions query. This has been found by manually examining the generated byte code of this query, finding that temporary index is created Signed-off-by: DL6ER --- src/database/common.c | 15 +++++++++++++++ src/database/network-table.c | 19 +++++++++++++++++++ src/database/network-table.h | 1 + src/database/query-table.h | 2 +- test/test_suite.bats | 4 +++- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/database/common.c b/src/database/common.c index f4943ea0..7917c5b9 100644 --- a/src/database/common.c +++ b/src/database/common.c @@ -601,6 +601,21 @@ void db_init(void) dbversion = db_get_int(db, DB_VERSION); } + // Update to version 20 if lower + if(dbversion < 20) + { + // Update to version 20: Add additional column for the network table + log_info("Updating long-term database to version 20"); + if(!create_network_addresses_network_id_index(db)) + { + log_info("Network addresses network_id index cannot be added, database not available"); + dbclose(&db); + return; + } + // Get updated version + dbversion = db_get_int(db, DB_VERSION); + } + /* * * * * * * * * * * * * IMPORTANT * * * * * * * * * * * * * * If you add a new database version, check if the in-memory * schema needs to be update as well (always recreated from diff --git a/src/database/network-table.c b/src/database/network-table.c index 23b2f874..486ba0bf 100644 --- a/src/database/network-table.c +++ b/src/database/network-table.c @@ -203,6 +203,25 @@ bool create_network_addresses_with_names_table(sqlite3 *db) return true; } +bool create_network_addresses_network_id_index(sqlite3 *db) +{ + // Return early if database is known to be broken + if(FTLDBerror()) + return false; + + // Create index on network_id column in network_addresses table + SQL_bool(db, "CREATE INDEX IF NOT EXISTS network_addresses_network_id_index ON network_addresses (network_id);"); + + // Update database version to 8 + if(!db_set_FTL_property(db, DB_VERSION, 20)) + { + log_warn("create_network_addresses_with_names_table(): Failed to update database version!"); + return false; + } + + return true; +} + // Try to find device by recent usage of this IP address static int find_device_by_recent_ip(sqlite3 *db, const char *ipaddr) { diff --git a/src/database/network-table.h b/src/database/network-table.h index 8da0fa3f..ce4debf4 100644 --- a/src/database/network-table.h +++ b/src/database/network-table.h @@ -15,6 +15,7 @@ bool create_network_table(sqlite3 *db); bool create_network_addresses_table(sqlite3 *db); bool create_network_addresses_with_names_table(sqlite3 *db); +bool create_network_addresses_network_id_index(sqlite3 *db); void parse_neighbor_cache(sqlite3 *db); void updateMACVendorRecords(sqlite3 *db); bool unify_hwaddr(sqlite3 *db); diff --git a/src/database/query-table.h b/src/database/query-table.h index 50d824f6..20b02e6c 100644 --- a/src/database/query-table.h +++ b/src/database/query-table.h @@ -23,7 +23,7 @@ "client TEXT NOT NULL, " \ "forward TEXT );" -#define MEMDB_VERSION 19 +#define MEMDB_VERSION 20 #define CREATE_QUERY_STORAGE_TABLE "CREATE TABLE query_storage ( id INTEGER PRIMARY KEY AUTOINCREMENT, " \ "timestamp INTEGER NOT NULL, " \ "type INTEGER NOT NULL, " \ diff --git a/test/test_suite.bats b/test/test_suite.bats index 133e3905..51ad12f9 100644 --- a/test/test_suite.bats +++ b/test/test_suite.bats @@ -699,7 +699,7 @@ [[ "${lines[@]}" == *"CREATE TABLE IF NOT EXISTS \"network\" (id INTEGER PRIMARY KEY NOT NULL, hwaddr TEXT UNIQUE NOT NULL, interface TEXT NOT NULL, firstSeen INTEGER NOT NULL, lastQuery INTEGER NOT NULL, numQueries INTEGER NOT NULL, macVendor TEXT, aliasclient_id INTEGER);"* ]] [[ "${lines[@]}" == *"CREATE TABLE IF NOT EXISTS \"network_addresses\" (network_id INTEGER NOT NULL, ip TEXT UNIQUE NOT NULL, lastSeen INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)), name TEXT, nameUpdated INTEGER, FOREIGN KEY(network_id) REFERENCES network(id));"* ]] [[ "${lines[@]}" == *"CREATE TABLE aliasclient (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, comment TEXT);"* ]] - [[ "${lines[@]}" == *"INSERT INTO ftl VALUES(0,19,'Database version');"* ]] + [[ "${lines[@]}" == *"INSERT INTO ftl VALUES(0,20,'Database version');"* ]] # vvv This has been added in version 10 vvv [[ "${lines[@]}" == *"CREATE VIEW queries AS SELECT id, timestamp, type, status, CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,CASE typeof(client) WHEN 'integer' THEN (SELECT ip FROM client_by_id c WHERE c.id = q.client) ELSE client END client,CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,CASE typeof(additional_info) WHEN 'integer' THEN (SELECT content FROM addinfo_by_id a WHERE a.id = q.additional_info) ELSE additional_info END additional_info, reply_type, reply_time, dnssec, list_id FROM query_storage q;"* ]] [[ "${lines[@]}" == *"CREATE TABLE domain_by_id (id INTEGER PRIMARY KEY, domain TEXT NOT NULL);"* ]] @@ -712,6 +712,8 @@ [[ "${lines[@]}" == *"CREATE UNIQUE INDEX addinfo_by_id_idx ON addinfo_by_id(type,content);"* ]] # vvv This has been added in version 15 vvv [[ "${lines[@]}" == *"CREATE TABLE session (id INTEGER PRIMARY KEY, login_at TIMESTAMP NOT NULL, valid_until TIMESTAMP NOT NULL, remote_addr TEXT NOT NULL, user_agent TEXT, sid TEXT NOT NULL, csrf TEXT NOT NULL, tls_login BOOL, tls_mixed BOOL, app BOOL, cli BOOL, x_forwarded_for TEXT);"* ]] + # vvv This has been added in version 20 vvv + [[ "${lines[@]}" == *"CREATE INDEX network_addresses_network_id_index ON network_addresses (network_id);"* ]] } @test "Ownership, permissions and type of pihole-FTL.db correct" {