-
wangteng authored
旧方案每页独立连接跑 LIMIT/OFFSET,页越深扫得越多(50万行=1000次建连+ 1000次全表扫描排序)。改为 /start 起 daemon 线程单连接 iter_rows 流式扫 全表一遍(保留 ORDER BY 首列,全表只排序一次),命中行进 session 缓冲区, 前端由 3-worker 分页队列改为轮询 /pull 增量拉取(满额立即续拉)。 后端: - queries.py:_scan_worker 扫描线程(cancelled 无锁读+关连接双保险、每 1000 行发布进度、命中超 10 万条截断只计数);/pull 游标切片;/cancel 摘 session+request_cancel;删 /page;_load_task_compiled 批量化(N+1→ 固定 4 条查询)+ 接入 compile_rule 预编译(regex 每行 re.compile、code 类每行 compile+exec 的量级浪费消除);/start 的 COUNT 与字段注释合并 单连接;并发扫描软上限 MAX_ACTIVE_SCANS=4 - session_manager.py:QuerySession 扩展流式扫描状态(scanned/bad_rows/ scan_done/scan_error/truncated,统一持锁读写),request_cancel() 幂等 取消(置标志+关连接),TTL 清理锁外停掉过期扫描线程 - db_adapter.py:DBConnection.close() 抽为 public 幂等(跨线程取消用); iter_rows finally 的 cur.close 包保护(取消关连接后 generator 提前退出) 前端: - queries.js:fetchPage → pullQuery(after 游标) - DataQualityView.vue:pollLoop 轮询器(404 分流本端取消/会话过期、网络 异常 2s 退避×3、done 定稿 toast);进度条改「已扫描 X/Y 条(百分比)」; 快照/续跑按 __row_index 去重适配;无规则任务提示修正(原误报"无数据") - client.js:错误对象挂 HTTP status 实测(37151 行任务):扫描 12.5s→0.9s;扫描期间 /api/health 均值 114ms→2.2ms;code 类规则求值 175x;命中结果与旧版逐字节一致。 Co-Authored-By:Claude Fable 5 <noreply@anthropic.com>
aeb29b90