perf(timeline): hoist prepared statement outside discussion thread loop

Moves the conn.prepare() call for fetching discussion notes outside the
per-discussion loop in collect_discussion_threads(). The SQL is identical
for every iteration, so preparing it once and rebinding parameters avoids
redundant statement compilation on each matched discussion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
teernisse
2026-02-13 14:56:29 -05:00
parent 59f65b127a
commit 94435c37f0

View File

@@ -411,6 +411,12 @@ fn collect_discussion_threads(
// Deduplicate by discussion_id // Deduplicate by discussion_id
let mut seen = HashSet::new(); let mut seen = HashSet::new();
let mut stmt = conn.prepare(
"SELECT id, author_username, body, created_at FROM notes
WHERE discussion_id = ?1 AND is_system = 0
ORDER BY created_at ASC",
)?;
for disc in matched_discussions { for disc in matched_discussions {
if !seen.insert(disc.discussion_id) { if !seen.insert(disc.discussion_id) {
continue; continue;
@@ -422,12 +428,6 @@ fn collect_discussion_threads(
None => continue, // entity not in seed or expanded set None => continue, // entity not in seed or expanded set
}; };
let mut stmt = conn.prepare(
"SELECT id, author_username, body, created_at FROM notes
WHERE discussion_id = ?1 AND is_system = 0
ORDER BY created_at ASC",
)?;
let rows = stmt.query_map(rusqlite::params![disc.discussion_id], |row| { let rows = stmt.query_map(rusqlite::params![disc.discussion_id], |row| {
Ok(( Ok((
row.get::<_, i64>(0)?, // id row.get::<_, i64>(0)?, // id