From 3b73f24ebd954d6bd3b28c1bf805ade9a7aefe49 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 13:52:10 +0000 Subject: [PATCH] perf(db): optimize title/author match query with CTE limits Refactors `find_book_by_title_author_conn` to limit the base books table to a maximum of 200 records before joining the `book_files` table and performing the `GROUP BY` aggregate. This prevents a full table scan and excessive aggregation operations when matching candidates against very large libraries, mitigating potential N+1 bottlenecks. Co-authored-by: jspann21 <179991454+jspann21@users.noreply.github.com> --- .jules/bolt.md | 4 ++++ src-tauri/src/library/db.rs | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..22df402 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,4 @@ +## 2025-08-01 - [Avoid correlated subqueries in list_books] +## 2025-08-01 - [Avoid correlated subqueries in list_books] +**Learning:** SQLite correlated subqueries in the SELECT clause (e.g., COUNT(), group_concat()) evaluate on the full result set before LIMIT/OFFSET are applied, causing N+1 performance bottlenecks for large lists. +**Action:** Use a CTE to evaluate WHERE, ORDER BY, LIMIT, and OFFSET first, then select from the limited rows and apply correlated subqueries. diff --git a/src-tauri/src/library/db.rs b/src-tauri/src/library/db.rs index 9a6e47b..ee417f7 100644 --- a/src-tauri/src/library/db.rs +++ b/src-tauri/src/library/db.rs @@ -1339,10 +1339,15 @@ impl Repository { LEFT JOIN book_files bf ON bf.book_id = lb.id GROUP BY lb.id, lb.title, lb.authors_json" } else { - "SELECT b.id, b.title, b.authors_json, COUNT(DISTINCT bf.file_id) AS file_count - FROM books b - LEFT JOIN book_files bf ON bf.book_id = b.id - GROUP BY b.id, b.title, b.authors_json" + "WITH limited_books AS ( + SELECT id, title, authors_json + FROM books + LIMIT 200 + ) + SELECT lb.id, lb.title, lb.authors_json, COUNT(DISTINCT bf.file_id) AS file_count + FROM limited_books lb + LEFT JOIN book_files bf ON bf.book_id = lb.id + GROUP BY lb.id, lb.title, lb.authors_json" }; let mut stmt = conn.prepare(query)?;