From b12a308997584fdaab4d566ee5ec5b37cfc1a92b Mon Sep 17 00:00:00 2001 From: cr0ss Date: Thu, 9 Jul 2026 13:12:39 +0200 Subject: [PATCH] Drop ivfflat index on contact_embeddings (breaks search on small tables) An ivfflat index with lists=100 + default probes=1 makes ORDER BY <=> queries scan only 1 of 100 clusters, silently returning zero rows on a small table. For a personal contact store an exact sequential scan is fast and correct. The live index is already dropped; this stops ai:setup from recreating it. --- scripts/setup-contacts-db.ts | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/scripts/setup-contacts-db.ts b/scripts/setup-contacts-db.ts index ea58fc9..52998fe 100644 --- a/scripts/setup-contacts-db.ts +++ b/scripts/setup-contacts-db.ts @@ -93,20 +93,13 @@ async function main() { CREATE INDEX IF NOT EXISTS contact_embeddings_profile_idx ON contact_embeddings USING gin (profile) `; - try { - await sql` - CREATE INDEX IF NOT EXISTS contact_embeddings_embedding_idx - ON contact_embeddings - USING ivfflat (embedding vector_cosine_ops) - WITH (lists = 100) - `; - console.log("✅ contact_embeddings table + vector index ready\n"); - } catch (error) { - console.log( - "⚠️ Vector index skipped (created after first rows):", - error instanceof Error ? error.message.split("\n")[0] : String(error) - ); - } + // No approximate vector index (ivfflat/hnsw) on purpose. A personal contact + // store is small, so an exact sequential scan is fast and always correct. + // An ivfflat index with lists=100 + default probes=1 silently returns zero + // rows on a tiny table (it only scans one of 100 clusters). Add HNSW only if + // this ever grows into the tens of thousands of contacts. + await sql`DROP INDEX IF EXISTS contact_embeddings_embedding_idx`; + console.log("✅ contact_embeddings table + indexes ready\n"); // 5. Verify console.log("5️⃣ Verifying tables...");