From 56a226a8c7254004c200ba05f74f33cb5a21f545 Mon Sep 17 00:00:00 2001 From: matevip Date: Sat, 16 May 2026 14:51:36 +0800 Subject: [PATCH] chore(db): index agent+filename and task conv+status read paths --- ...kspace_memory_search_and_async_indexes.sql | 21 ++++++++++ ...kspace_memory_search_and_async_indexes.sql | 38 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 mateclaw-server/src/main/resources/db/migration/h2/V113__workspace_memory_search_and_async_indexes.sql create mode 100644 mateclaw-server/src/main/resources/db/migration/mysql/V113__workspace_memory_search_and_async_indexes.sql diff --git a/mateclaw-server/src/main/resources/db/migration/h2/V113__workspace_memory_search_and_async_indexes.sql b/mateclaw-server/src/main/resources/db/migration/h2/V113__workspace_memory_search_and_async_indexes.sql new file mode 100644 index 00000000..09a85a1b --- /dev/null +++ b/mateclaw-server/src/main/resources/db/migration/h2/V113__workspace_memory_search_and_async_indexes.sql @@ -0,0 +1,21 @@ +-- Indexes for two recently-added read paths. +-- +-- (1) idx_workspace_file_agent_filename — accelerates the memory search tool +-- on mate_workspace_file. The query is "agent_id = ? AND filename LIKE +-- 'prefix%' AND content LIKE '%term%'"; the existing single-column +-- idx_workspace_file_agent covers only the equality, so the filename +-- prefix scan still had to walk every row for an agent that owns +-- hundreds of daily notes. The compound (agent_id, filename) lets the +-- planner narrow on both columns in one index probe. +-- +-- (2) idx_async_task_conv_status — accelerates listActiveTasks(conversationId). +-- The SQL is "WHERE conversation_id = ? AND status IN ('pending', +-- 'running')". A single-column idx_async_task_conv alone still forces +-- a row scan to filter on status; the compound (conversation_id, status) +-- resolves both predicates in one index seek. + +CREATE INDEX IF NOT EXISTS idx_workspace_file_agent_filename + ON mate_workspace_file (agent_id, filename); + +CREATE INDEX IF NOT EXISTS idx_async_task_conv_status + ON mate_async_task (conversation_id, status); diff --git a/mateclaw-server/src/main/resources/db/migration/mysql/V113__workspace_memory_search_and_async_indexes.sql b/mateclaw-server/src/main/resources/db/migration/mysql/V113__workspace_memory_search_and_async_indexes.sql new file mode 100644 index 00000000..5ee39bd0 --- /dev/null +++ b/mateclaw-server/src/main/resources/db/migration/mysql/V113__workspace_memory_search_and_async_indexes.sql @@ -0,0 +1,38 @@ +-- Indexes for two recently-added read paths. Mirrors the H2 file in this +-- migration set; MySQL < 8.0.29 has no CREATE INDEX IF NOT EXISTS, so each +-- index is guarded by an INFORMATION_SCHEMA.STATISTICS check and applied via +-- a prepared statement when missing (matches the pattern in V69, V83, V93). +-- +-- (1) idx_workspace_file_agent_filename — accelerates the memory search tool +-- on mate_workspace_file ("agent_id = ? AND filename LIKE 'prefix%' AND +-- content LIKE '%term%'"). A 64-char filename prefix is used because the +-- full filename column is VARCHAR(256); under utf8mb4 the full column +-- would chew through too much of the 3072-byte composite-key budget for +-- no real benefit (every memory filename fits within 64 chars). +-- +-- (2) idx_async_task_conv_status — accelerates listActiveTasks(conversationId) +-- ("WHERE conversation_id = ? AND status IN ('pending', 'running')"). +-- The existing single-column idx_async_task_conv left the status filter +-- to a row scan; the compound resolves both in one index seek. + +SET @idx_exists := ( + SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'mate_workspace_file' + AND INDEX_NAME = 'idx_workspace_file_agent_filename' +); +SET @stmt := IF(@idx_exists = 0, + 'CREATE INDEX idx_workspace_file_agent_filename ON mate_workspace_file (agent_id, filename(64))', + 'SELECT 1'); +PREPARE s FROM @stmt; EXECUTE s; DEALLOCATE PREPARE s; + +SET @idx_exists := ( + SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'mate_async_task' + AND INDEX_NAME = 'idx_async_task_conv_status' +); +SET @stmt := IF(@idx_exists = 0, + 'CREATE INDEX idx_async_task_conv_status ON mate_async_task (conversation_id, status)', + 'SELECT 1'); +PREPARE s FROM @stmt; EXECUTE s; DEALLOCATE PREPARE s;