性能优化(二)流式扫描:OFFSET 深分页 → 后端单连接流式扫描 + /pull 轮询
旧方案每页独立连接跑 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>
Showing
Please register or sign in to comment