From 82059bac4a817f19664c893439da244f490e15d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Mon, 22 Jun 2026 01:24:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96:=20tasks=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E8=A1=A5=E5=85=A8(V26=20priority+assignee?= =?UTF-8?q?=E7=B4=A2=E5=BC=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit list_by_query已支持priority/assignee过滤下推,缺索引致全表扫描 migrate_v26 CREATE INDEX IF NOT EXISTS补建(老库幂等) V1_SQL同步加(新库一次性建),对齐idx_tasks_status同类维度 数据量~15前瞻基建,为后续priority排序/分配人筛选铺路 --- crates/df-storage/src/migrations.rs | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/df-storage/src/migrations.rs b/crates/df-storage/src/migrations.rs index d6e8d98..3fcbfe0 100644 --- a/crates/df-storage/src/migrations.rs +++ b/crates/df-storage/src/migrations.rs @@ -27,8 +27,9 @@ pub fn run(conn: &Connection) -> Result<()> { // V22 = 灵感评估历史持久化(idea_evaluations 追加型审计表); // V23 = knowledges.embedding_status 列(嵌入失败可补偿重试); // V24 = ideas.related_ids 列(灵感间关联关系持久化打底); - // V25 = idea_evaluations (idea_id, version) 唯一约束(评估版本并发重复兜底)。 - let steps: [(i32, fn(&Connection) -> Result<()>); 25] = [ + // V25 = idea_evaluations (idea_id, version) 唯一约束(评估版本并发重复兜底); + // V26 = F-260621-02 任务索引缺口补全(priority/assignee,对齐 idx_tasks_status 同类索引)。 + let steps: [(i32, fn(&Connection) -> Result<()>); 26] = [ (1, migrate_v1), (2, migrate_v2), (3, migrate_v3), @@ -54,6 +55,7 @@ pub fn run(conn: &Connection) -> Result<()> { (23, migrate_v23), (24, migrate_v24), (25, migrate_v25), + (26, migrate_v26), ]; for (version, migrate_fn) in steps { @@ -632,6 +634,29 @@ fn migrate_v25(conn: &Connection) -> Result<()> { Ok(()) } +/// V26:补建 tasks 表 priority/assignee 索引(F-260621-02 索引缺口) +/// +/// list_by_query 已支持 priority/assignee 过滤下推(TaskQuery.priority/assignee), +/// 但缺索引 → 数据量增长后全表扫描。补建索引对齐已有的 idx_tasks_status / +/// idx_tasks_project_id 同类过滤维度。当前数据量 ~15(前瞻基建非性能驱动), +/// 但索引零成本(SQLite 维护代价极小)且向后续 priority 排序/分配人筛选铺路。 +/// +/// 实现选 CREATE INDEX IF NOT EXISTS:原生幂等(新库 V1_SQL 已建则跳过, +/// 老库无则补建),对新库与老库均安全,无需 PRAGMA 探测。索引定义须与 V1_SQL 中 +/// 的同名索引一致(仅 priority/assignee 单列索引)。 +/// +/// 注:assignee 列允许 NULL(V1_SQL 未 NOT NULL),SQLite 索引正常包含 NULL 行, +/// 不影响 assignee = ? 等值查询命中(过滤掉 NULL 行)。 +fn migrate_v26(conn: &Connection) -> Result<()> { + conn.execute_batch( + "CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);\ + CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee)", + )?; + conn.execute("INSERT INTO schema_version (version) VALUES (?)", [26])?; + tracing::info!("迁移 v26 完成"); + Ok(()) +} + /// V21 建表 SQL — 消息拆分存储 ai_messages 表 /// /// 与 V9_SQL 中的 ai_messages 镜像(V9 给新库,此 const 给老库 V21 迁移用 IF NOT EXISTS)。 @@ -762,6 +787,10 @@ CREATE TABLE IF NOT EXISTS node_executions ( -- 索引 CREATE INDEX IF NOT EXISTS idx_tasks_project_id ON tasks(project_id); CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status); +-- V26 补建(F-260621-02 索引缺口):priority/assignee 过滤下推索引,新库一次性建; +-- 老库由 migrate_v26 CREATE INDEX IF NOT EXISTS 补建,两边索引定义须一致。 +CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority); +CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee); CREATE INDEX IF NOT EXISTS idx_releases_project_id ON releases(project_id); CREATE INDEX IF NOT EXISTS idx_node_executions_workflow_id ON node_executions(workflow_id); ";