perf(P1): 批量插入性能悬崖 — insert 循环内逐行 prefetchKeys(每行 await drainChain 排空后台链),compaction 在链上数秒时每行阻塞数秒 → kv 后端 10 万行插入 353s;改为批级预加载本批 PK 一次,实测 353s→12.5s(28 倍)/ opfs 25s;新增 kv/opfs 双后端 10 万行回归(性能护栏+索引完整+崩溃恢复),aria-cache 测试同步适配显式 flush
CI / test (18.x) (push) Successful in 18m51s
CI / test (20.x) (push) Successful in 17m42s
CI / test (22.x) (push) Successful in 16m58s
CI / test (24.x) (push) Failing after 14m38s
CI / e2e (push) Successful in 10m36s

This commit is contained in:
thzxx
2026-08-10 20:14:57 +08:00
parent 34225a86b3
commit d83910832e
4 changed files with 97 additions and 1 deletions
+7 -1
View File
@@ -537,13 +537,19 @@ export class AriaEngine implements IStorageEngine {
// v0.3.1: 批量 WAL 写入(组提交),一次 insert 合并为一次落盘
const walRecords: Omit<WALRecord, 'lsn' | 'checksum'>[] = [];
// v0.6.1-perf: 批量预加载本批 PK 涉及的 SSTable(一次 drainChain)。
// 此前循环内逐行 prefetchKeys —— 每行 await drainChain 排空后台链,
// 后台 compaction 在链上数秒时每行阻塞数秒 → 大数据量插入性能悬崖
// 10 万行 kv 后端从 5ms/批暴跌到 8~11s/批)。批内新数据在 memtable
// 或 flush 产物(自动入缓存),循环内 lsm.get 始终完整。
await this.lsm.prefetchKeys(rows.map((r) => `${tableName}:${String(r[pkCol])}`));
for (const row of rows) {
const validated = this.validateRow(schema, row);
const pkValue = String(validated[pkCol]);
const key = `${tableName}:${pkValue}`;
// Check duplicate in LSM + transaction snapshot
await this.lsm.prefetchKeys([key]);
const existing = this.currentTxnId
? (this.txnSnapshot?.get(key) ?? this.lsm.get(key))
: this.lsm.get(key);