======================================================================================================== P0 环境与参数 ======================================================================================================== 时间 : 2026-09-15 09:46:02 Go : go1.24.5 | CPU 8 核 (GOMAXPROCS=8) | darwin/amd64 规模 : 主表 10000000 行 | 订单 1000000 行 | 部门 100 行 | 单行更新 2000 次 | 逐行删除 100000 行 参数 : Age=20+No%50 | Score=No%1000 | Dept=Dept(No%100) | Salary=No%100000 索引 : pk_emp + idx_emp_no/BTree + idx_emp_age/BTree + idx_emp_dept/BTree 提交策略 : preset=batch(脏页阈值 500 页), 自动提交防抖禁用, 每 100 万行显式 Commit 主库 : /Users/yl32940/Projects/TsDB2/demo/bench_10m/bench_10m.db 探针库 : /Users/yl32940/Projects/TsDB2/demo/bench_10m/bench_10m_probe.db GoAlloc=0MB Sys=6MB HeapInuse=0MB NumGC=0 清理同前缀旧库文件... ======================================================================================================== P1 建表 / 打开表 + 索引 ======================================================================================================== UseTable × 3 (含建表/建索引) 行数=3 耗时=1ms 5.91k/s emp 活跃列 : [_id No Name Age Score Dept Salary Active] emp 字段数 : 总 8 / 活跃 8 | TotalRows=0 索引 pk_emp type=2 分量=1 fieldIDs=[0] 索引 idx_emp_no type=5 分量=1 fieldIDs=[1] 索引 idx_emp_age type=5 分量=1 fieldIDs=[3] 索引 idx_emp_dept type=5 分量=1 fieldIDs=[5] ======================================================================================================== P2 千万级写入: 单行 Insert × 10000000 (含进度 / 分档 Commit) ======================================================================================================== [ 200000 行] 累计 8.1s | 瞬时 24.72k/s | 磁盘 44.6MB | ETA 6m37s | GoAlloc=26MB Sys=73MB HeapInuse=26MB NumGC=1124 [ 400000 行] 累计 16.4s | 瞬时 24.00k/s | 磁盘 87.6MB | ETA 6m40s | GoAlloc=24MB Sys=77MB HeapInuse=25MB NumGC=1791 [ 600000 行] 累计 25.1s | 瞬时 23.15k/s | 磁盘 130.3MB | ETA 6m46s | GoAlloc=28MB Sys=77MB HeapInuse=29MB NumGC=2461 [ 800000 行] 累计 34.4s | 瞬时 21.37k/s | 磁盘 172.8MB | ETA 7m11s | GoAlloc=27MB Sys=77MB HeapInuse=27MB NumGC=3133 [ 1000000 行] 累计 43.8s | 瞬时 21.24k/s | 磁盘 214.8MB | ETA 7m4s | GoAlloc=20MB Sys=77MB HeapInuse=21MB NumGC=3803 [ 1000000 行] 显式 Commit 30ms | 磁盘 214.8MB [ 1200000 行] 累计 53.4s | 瞬时 20.90k/s | 磁盘 253.2MB | ETA 7m1s | GoAlloc=29MB Sys=77MB HeapInuse=30MB NumGC=4468 [ 1400000 行] 累计 63.0s | 瞬时 20.87k/s | 磁盘 295.0MB | ETA 6m52s | GoAlloc=31MB Sys=77MB HeapInuse=31MB NumGC=5136 [ 1600000 行] 累计 73.5s | 瞬时 19.09k/s | 磁盘 336.8MB | ETA 7m20s | GoAlloc=29MB Sys=77MB HeapInuse=29MB NumGC=5813 [ 1800000 行] 累计 84.0s | 瞬时 19.06k/s | 磁盘 377.4MB | ETA 7m10s | GoAlloc=21MB Sys=77MB HeapInuse=21MB NumGC=6684 [ 2000000 行] 累计 95.2s | 瞬时 17.74k/s | 磁盘 421.7MB | ETA 7m31s | GoAlloc=28MB Sys=77MB HeapInuse=29MB NumGC=7557 [ 2000000 行] 显式 Commit 38ms | 磁盘 421.7MB [ 2200000 行] 累计 106.6s | 瞬时 17.64k/s | 磁盘 463.1MB | ETA 7m22s | GoAlloc=22MB Sys=77MB HeapInuse=23MB NumGC=8429 [ 2400000 行] 累计 118.2s | 瞬时 17.27k/s | 磁盘 503.6MB | ETA 7m20s | GoAlloc=23MB Sys=77MB HeapInuse=23MB NumGC=9303 [ 2600000 行] 累计 129.5s | 瞬时 17.64k/s | 磁盘 547.4MB | ETA 7m0s | GoAlloc=31MB Sys=77MB HeapInuse=32MB NumGC=10175 [ 2800000 行] 累计 140.8s | 瞬时 17.68k/s | 磁盘 588.1MB | ETA 6m47s | GoAlloc=18MB Sys=77MB HeapInuse=19MB NumGC=11048 [ 3000000 行] 累计 152.1s | 瞬时 17.70k/s | 磁盘 628.5MB | ETA 6m36s | GoAlloc=20MB Sys=77MB HeapInuse=21MB NumGC=11919 [ 3000000 行] 显式 Commit 38ms | 磁盘 628.5MB [ 3200000 行] 累计 163.3s | 瞬时 17.85k/s | 磁盘 670.1MB | ETA 6m21s | GoAlloc=30MB Sys=77MB HeapInuse=31MB NumGC=12792 [ 3400000 行] 累计 174.4s | 瞬时 18.09k/s | 磁盘 713.0MB | ETA 6m5s | GoAlloc=31MB Sys=77MB HeapInuse=31MB NumGC=13667 [ 3600000 行] 累计 185.7s | 瞬时 17.59k/s | 磁盘 754.3MB | ETA 6m4s | GoAlloc=17MB Sys=77MB HeapInuse=18MB NumGC=14543 [ 3800000 行] 累计 197.1s | 瞬时 17.65k/s | 磁盘 795.6MB | ETA 5m51s | GoAlloc=26MB Sys=77MB HeapInuse=26MB NumGC=15418 [ 4000000 行] 累计 208.5s | 瞬时 17.46k/s | 磁盘 837.6MB | ETA 5m44s | GoAlloc=18MB Sys=77MB HeapInuse=18MB NumGC=16292 [ 4000000 行] 显式 Commit 40ms | 磁盘 837.6MB [ 4200000 行] 累计 220.0s | 瞬时 17.36k/s | 磁盘 880.4MB | ETA 5m34s | GoAlloc=53MB Sys=77MB HeapInuse=54MB NumGC=17166 [ 4400000 行] 累计 231.6s | 瞬时 17.30k/s | 磁盘 919.0MB | ETA 5m24s | GoAlloc=25MB Sys=77MB HeapInuse=25MB NumGC=18038 [ 4600000 行] 累计 243.1s | 瞬时 17.43k/s | 磁盘 961.0MB | ETA 5m10s | GoAlloc=32MB Sys=77MB HeapInuse=32MB NumGC=18913 [ 4800000 行] 累计 254.4s | 瞬时 17.61k/s | 磁盘 1002.0MB | ETA 4m55s | GoAlloc=30MB Sys=77MB HeapInuse=31MB NumGC=19788 [ 5000000 行] 累计 265.8s | 瞬时 17.56k/s | 磁盘 1043.5MB | ETA 4m45s | GoAlloc=22MB Sys=77MB HeapInuse=23MB NumGC=20662 [ 5000000 行] 显式 Commit 47ms | 磁盘 1044.0MB [ 5200000 行] 累计 277.3s | 瞬时 17.45k/s | 磁盘 1087.1MB | ETA 4m35s | GoAlloc=17MB Sys=77MB HeapInuse=18MB NumGC=21538 [ 5400000 行] 累计 288.8s | 瞬时 17.38k/s | 磁盘 1128.6MB | ETA 4m25s | GoAlloc=20MB Sys=77MB HeapInuse=21MB NumGC=22412 [ 5600000 行] 累计 300.3s | 瞬时 17.37k/s | 磁盘 1170.5MB | ETA 4m13s | GoAlloc=16MB Sys=77MB HeapInuse=17MB NumGC=23289 [ 5800000 行] 累计 311.7s | 瞬时 17.55k/s | 磁盘 1212.1MB | ETA 3m59s | GoAlloc=23MB Sys=77MB HeapInuse=23MB NumGC=24161 [ 6000000 行] 累计 323.1s | 瞬时 17.62k/s | 磁盘 1253.1MB | ETA 3m47s | GoAlloc=18MB Sys=77MB HeapInuse=19MB NumGC=25034 [ 6000000 行] 显式 Commit 30ms | 磁盘 1253.1MB [ 6200000 行] 累计 334.6s | 瞬时 17.37k/s | 磁盘 1294.7MB | ETA 3m39s | GoAlloc=30MB Sys=77MB HeapInuse=30MB NumGC=25908 [ 6400000 行] 累计 345.8s | 瞬时 17.85k/s | 磁盘 1335.8MB | ETA 3m22s | GoAlloc=21MB Sys=77MB HeapInuse=22MB NumGC=26782 [ 6600000 行] 累计 357.0s | 瞬时 17.84k/s | 磁盘 1376.5MB | ETA 3m11s | GoAlloc=21MB Sys=77MB HeapInuse=22MB NumGC=27656 [ 6800000 行] 累计 368.9s | 瞬时 16.87k/s | 磁盘 1420.0MB | ETA 3m10s | GoAlloc=25MB Sys=77MB HeapInuse=26MB NumGC=28531 [ 7000000 行] 累计 380.8s | 瞬时 16.72k/s | 磁盘 1460.3MB | ETA 2m59s | GoAlloc=23MB Sys=77MB HeapInuse=23MB NumGC=29406 [ 7000000 行] 显式 Commit 56ms | 磁盘 1461.9MB [ 7200000 行] 累计 392.4s | 瞬时 17.35k/s | 磁盘 1502.2MB | ETA 2m41s | GoAlloc=20MB Sys=77MB HeapInuse=21MB NumGC=30280 [ 7400000 行] 累计 403.9s | 瞬时 17.38k/s | 磁盘 1544.7MB | ETA 2m30s | GoAlloc=23MB Sys=77MB HeapInuse=24MB NumGC=31155 [ 7600000 行] 累计 415.7s | 瞬时 16.93k/s | 磁盘 1583.6MB | ETA 2m22s | GoAlloc=19MB Sys=77MB HeapInuse=20MB NumGC=32030 [ 7800000 行] 累计 427.8s | 瞬时 16.49k/s | 磁盘 1626.1MB | ETA 2m13s | GoAlloc=30MB Sys=77MB HeapInuse=30MB NumGC=32905 [ 8000000 行] 累计 439.2s | 瞬时 17.57k/s | 磁盘 1668.6MB | ETA 1m54s | GoAlloc=28MB Sys=77MB HeapInuse=29MB NumGC=33780 [ 8000000 行] 显式 Commit 37ms | 磁盘 1668.6MB [ 8200000 行] 累计 450.9s | 瞬时 17.02k/s | 磁盘 1709.3MB | ETA 1m46s | GoAlloc=17MB Sys=77MB HeapInuse=18MB NumGC=34656 [ 8400000 行] 累计 462.6s | 瞬时 17.10k/s | 磁盘 1751.8MB | ETA 1m34s | GoAlloc=17MB Sys=77MB HeapInuse=17MB NumGC=35532 [ 8600000 行] 累计 474.3s | 瞬时 17.09k/s | 磁盘 1794.3MB | ETA 1m22s | GoAlloc=23MB Sys=77MB HeapInuse=23MB NumGC=36407 [ 8800000 行] 累计 485.9s | 瞬时 17.28k/s | 磁盘 1833.5MB | ETA 1m9s | GoAlloc=23MB Sys=77MB HeapInuse=23MB NumGC=37284 [ 9000000 行] 累计 497.6s | 瞬时 17.16k/s | 磁盘 1876.0MB | ETA 58s | GoAlloc=17MB Sys=77MB HeapInuse=17MB NumGC=38160 [ 9000000 行] 显式 Commit 45ms | 磁盘 1876.0MB [ 9200000 行] 累计 509.2s | 瞬时 17.12k/s | 磁盘 1917.1MB | ETA 47s | GoAlloc=28MB Sys=77MB HeapInuse=28MB NumGC=39036 [ 9400000 行] 累计 521.0s | 瞬时 17.03k/s | 磁盘 1959.5MB | ETA 35s | GoAlloc=18MB Sys=77MB HeapInuse=19MB NumGC=39914 [ 9600000 行] 累计 532.6s | 瞬时 17.21k/s | 磁盘 2002.0MB | ETA 23s | GoAlloc=18MB Sys=77MB HeapInuse=19MB NumGC=40787 [ 9800000 行] 累计 544.2s | 瞬时 17.26k/s | 磁盘 2041.4MB | ETA 12s | GoAlloc=24MB Sys=77MB HeapInuse=24MB NumGC=41660 [ 10000000 行] 累计 555.7s | 瞬时 17.43k/s | 磁盘 2083.9MB | ETA 0s | GoAlloc=28MB Sys=77MB HeapInuse=29MB NumGC=42536 [ 10000000 行] 显式 Commit 53ms | 磁盘 2085.1MB 单行 Insert × 10000000 + 分档 Commit 行数=10000000 耗时=9m15.718s 17.99k/s 最终 Commit 0s | 磁盘 2085.1MB | 文件 2.04GB | GoAlloc=38MB Sys=77MB HeapInuse=38MB NumGC=42538 全表扫描 写入后全量校验(插入态) 行数=10000000 耗时=23.994s 416.77k/s ======================================================================================================== P3 查询性能 (主键点查 / 二级索引等值 / 范围 / 分页 / 排序 / 投影 / 聚合) ======================================================================================================== 主键点查 Find(pkID) × 20000 行数=20000 耗时=576ms 34.73k/s 二级索引等值 Where(No=..) × 20000 行数=20000 耗时=1.417s 14.12k/s 索引等值 Count(Age=..) × 20 (每次 200000 行) 行数=4000000 耗时=230ms 17.39M/s 索引范围 Count(Age 30..34, 1000000 行) 行数=1000000 耗时=39ms 25.45M/s 字符串索引 Count(Dept=Dept007, 100000 行) 行数=100000 耗时=9ms 10.92M/s 无索引条件 Count(Score=123, 10000 行) 全表扫描 行数=10000000 耗时=5.401s 1.85M/s Limit(10).Offset(500) 行数=10 耗时=21ms 482/s OrderBy(索引列 Age) + Limit(10) 流式取前 N 行数=10 耗时=54ms 184/s OrderBy(非索引列 Score) 100000 行参与内存排序 行数=100000 耗时=2.824s 35.41k/s Select(No,Age) 首行返回: No=1 Age=21 Sum(Salary) 全表 行数=10000000 耗时=3.147s 3.18M/s Max(No) 行数=10000000 耗时=0s 234967.93M/s ======================================================================================================== P4 多表: 部门维度表 + 订单表 + 索引关联计数校验 ======================================================================================================== 维度表 dept_dim 写入 100 行 行数=100 耗时=19ms 5.39k/s [订单 200000 行] 累计 5.7s | 35.15k/s | 磁盘 2109.3MB [订单 400000 行] 累计 11.9s | 33.47k/s | 磁盘 2134.2MB [订单 600000 行] 累计 18.5s | 32.46k/s | 磁盘 2159.2MB [订单 800000 行] 累计 25.5s | 31.38k/s | 磁盘 2186.3MB [订单 1000000 行] 累计 32.9s | 30.40k/s | 磁盘 2214.5MB 订单表 orders 写入 1000000 行 行数=1000000 耗时=32.943s 30.36k/s 关联计数: 订单表按 EmpNo 索引 × 20 行数=20 耗时=1ms 27.69k/s 关联计数: 员工表按 Dept 索引 × 100 (每次 100000 行) 行数=10000000 耗时=877ms 11.40M/s ======================================================================================================== P5 更新 (单行整行重写 / core 批量更新 / 索引列更新后索引是否同步) ======================================================================================================== 单行更新 Update(整行重写) × 2000 行数=2000 耗时=150ms 13.32k/s core 批量更新 Updater.Exec (Score=500 → Age=99) 行数=10000 耗时=8.363s 1.20k/s 索引列更新后 Count(Age=99) 行数=10000 耗时=0s 20.95M/s core 批量更新字符串索引列 (Score=321 → Dept=Dept099) 行数=10000 耗时=8.516s 1.17k/s ======================================================================================================== P6 删除 (逐行删 100000 行 / 批量删除全表重建) + 全量一致性校验 ======================================================================================================== 逐行 Delete(pkID) × 100000 行数=100000 耗时=22.002s 4.55k/s 批量删除 orders (Status=0, 200000 行) 触发全表重建 行数=200000 耗时=5.216s 38.34k/s 批量删除后 员工→订单 关联计数 × 20 行数=20 耗时=1ms 23.49k/s --- 6.3 一致性校验 (更新 + 删除之后, 期望值由公式推导) --- 全表扫描 删除后全量校验(公式) 行数=9900000 耗时=23.312s 424.67k/s 索引计数复核 Dept × 100 行数=9900000 耗时=866ms 11.43M/s ======================================================================================================== P7 Schema 变更: 增列 / 删列 / 改列名 (含数据正确性校验) ======================================================================================================== --- 7.0 变更前基线 --- 活跃列: [_id No Name Age Score Dept Salary Active] TotalRows=9900000 | 字段数 总8/活跃8 基线行 No=3333333 → _id=3333333 No=3333333 Name=Emp03333333 Age=53 Score=333 Dept=Dept033 Salary=33333 Active=false --- 7.1 ADD COLUMN Level (8 字节新列) --- --- 7.2 在新增列上建索引 --- 新增列索引 Count(Level=777) 行数=3 耗时=1ms 3.00k/s --- 7.3 DROP COLUMN Level (先 DropIndex 再 DropField) --- --- 7.4 改列名 (引擎无 RENAME API, 只能 DROP 旧列 + ADD 新列) --- 证据: 老行 Dept 原值="Dept033", 改名后既读不到 Dept 也读不到 DeptName [设计约束] 引擎没有 RENAME COLUMN / RENAME TABLE API: 改列名只能 DROP 旧列 + ADD 新列; 老行原值不会被迁移到新列名(数据仍在行内, 只是列名不可达), 需要业务侧自行回填 --- 7.5 重新加回同名 Dept 列 (DropField 实为软删除) --- [重要语义] DROP COLUMN 是软删除, 数据仍留在行内; 重新 ADD 同名列会"复活"老行数据: 这解释了为什么改列名(删+加新名)后数据看似丢失, 但加回旧列名后又能读到 → 敏感数据无法靠删列来清除, 需要重建表/覆写 --- 7.6 重建 Dept 索引 + core 层全表校验 --- 重建索引后 索引计数复核 Dept × 100 行数=9900003 耗时=645ms 15.36M/s core 全表扫描 P7 变更后全量校验 行数=9900003 耗时=26.129s 378.89k/s [已关库] 磁盘 2256.8MB | GoAlloc=21MB Sys=1218MB HeapInuse=22MB NumGC=53668 ======================================================================================================== P8 引擎语义探针 (独立库 bench_10m_probe.db, 不影响主库) ======================================================================================================== --- T1 core 建表(无 _id 列) 时, Delete/Update 如何确定 pkID --- 表 = [No(8B), Label(32B)], 无 _id 列; 引擎反序列化出的行: No=5 Label=L1 数据: pkID 1→No5, 2→No5, 3→No5, 4→No6, 5→No7 Delete(No==5) → cnt=3 err= | 剩余: pkID4(No=6) pkID5(No=7) | TotalRows=2 Update(No==6 → Label=X) → cnt=1 err= 对照: ORM 表的行首列是 _id(=pkID), 因此 ORM 路径不受影响; 纯 core 表需自行保证首列语义 --- T2 只删列不删索引: 残留索引的行为 --- 删列前 Count(Tag==20)=1 err= 删列后活跃列=[No] 残留索引 idx_probe_tag 仍存在=true 删列后按残留索引查询 Tag==20 → err= 删列后插入不含 Tag 的新行 → err= TotalRows=6 读回新行: No=6 err= --- T3 ORM 显式指定 _id ≠ 引擎 pkID --- Insert(ID=999999) → err=, 对象 ID=999999 Find(999999) → err= Find(1) → err=key not found --- T4 删除中间 pkID 后再插入: pkID 复用与碰撞 --- 插 3 行(pkID 1,2,3) → 删 pkID=2 → Count=2 TotalRows=2 再插 1 行(No=99) 后存活: {_id=1,No=1} {_id=3,No=3} {_id=4,No=99} | Count=3 TotalRows=3 --- T5 float64 列的小数精度 --- 写入 Salary=123.75 → 读回 123.75 ======================================================================================================== P9 关库重开: 持久化 / schema / 索引 校验 ======================================================================================================== 重开后 emp 活跃列: [_id No Name Age Score Salary Active DeptName Dept] TotalRows=9900003 (期望 9900003) | 磁盘 2257.5MB core 全表扫描 重开后 core 全量校验 行数=9900003 耗时=27.239s 363.45k/s --- 9.2 ORM 重开表 (UseTable 会按 struct 同步 schema) --- UseTable[Emp] 之后活跃列: [_id No Name Age Score Salary Active Dept] [风险] ORM 重开表会按 struct 强制同步 schema, 静默删除 struct 里没有的列: 纯 core 视角活跃列=[_id No Name Age Score Salary Active DeptName Dept] 含 DeptName, 调用 UseTable[Emp] 后活跃列=[_id No Name Age Score Salary Active Dept], DeptName 被自动 DropField; 手工加过列的表被 ORM 打开就会"丢列"(数据仍在行内, 再加回同名列可复活) 全表扫描 重开后 ORM 全量校验 行数=9900003 耗时=24.085s 411.05k/s ======================================================================================================== P10 汇总报告 ======================================================================================================== 【性能总表】共 32 项 阶段 操作 行数 耗时 速率 ------------------------------------------------------------------------------------------------------------ P1 建表 UseTable × 3 (含建表/建索引) 3 1ms 5.91k/s P2 写入 单行 Insert × 10000000 + 分档 Commit 10000000 9m15.718s 17.99k/s 校验 全表扫描 写入后全量校验(插入态) 10000000 23.994s 416.77k/s P3 查询 主键点查 Find(pkID) × 20000 20000 576ms 34.73k/s P3 查询 二级索引等值 Where(No=..) × 20000 20000 1.417s 14.12k/s P3 查询 索引等值 Count(Age=..) × 20 (每次 200000 行) 4000000 230ms 17.39M/s P3 查询 索引范围 Count(Age 30..34, 1000000 行) 1000000 39ms 25.45M/s P3 查询 字符串索引 Count(Dept=Dept007, 100000 行) 100000 9ms 10.92M/s P3 查询 无索引条件 Count(Score=123, 10000 行) 全表扫描 10000000 5.401s 1.85M/s P3 查询 Limit(10).Offset(500) 10 21ms 482/s P3 查询 OrderBy(索引列 Age) + Limit(10) 流式取前 N 10 54ms 184/s P3 查询 OrderBy(非索引列 Score) 100000 行参与内存排序 100000 2.824s 35.41k/s P3 聚合 Sum(Salary) 全表 10000000 3.147s 3.18M/s P3 聚合 Max(No) 10000000 0s 234967.93M/s P4 多表 维度表 dept_dim 写入 100 行 100 19ms 5.39k/s P4 多表 订单表 orders 写入 1000000 行 1000000 32.943s 30.36k/s P4 多表 关联计数: 订单表按 EmpNo 索引 × 20 20 1ms 27.69k/s P4 多表 关联计数: 员工表按 Dept 索引 × 100 (每次 100000 行) 10000000 877ms 11.40M/s P5 更新 单行更新 Update(整行重写) × 2000 2000 150ms 13.32k/s P5 更新 core 批量更新 Updater.Exec (Score=500 → Age=99) 10000 8.363s 1.20k/s P5 校验 索引列更新后 Count(Age=99) 10000 0s 20.95M/s P5 更新 core 批量更新字符串索引列 (Score=321 → Dept=Dept099) 10000 8.516s 1.17k/s P6 删除 逐行 Delete(pkID) × 100000 100000 22.002s 4.55k/s P6 删除 批量删除 orders (Status=0, 200000 行) 触发全表重建 200000 5.216s 38.34k/s P6 校验 批量删除后 员工→订单 关联计数 × 20 20 1ms 23.49k/s 校验 全表扫描 删除后全量校验(公式) 9900000 23.312s 424.67k/s P6 校验 索引计数复核 Dept × 100 9900000 866ms 11.43M/s P7 校验 新增列索引 Count(Level=777) 3 1ms 3.00k/s P7 校验 重建索引后 索引计数复核 Dept × 100 9900003 645ms 15.36M/s 校验 core 全表扫描 P7 变更后全量校验 9900003 26.129s 378.89k/s 校验 core 全表扫描 重开后 core 全量校验 9900003 27.239s 363.45k/s 校验 全表扫描 重开后 ORM 全量校验 9900003 24.085s 411.05k/s 【校验总表】共 87 项: 通过 87, 失败 0 【数据问题清单】共 3 项 1. [设计约束] 引擎没有 RENAME COLUMN / RENAME TABLE API 改列名只能 DROP 旧列 + ADD 新列; 老行原值不会被迁移到新列名(数据仍在行内, 只是列名不可达), 需要业务侧自行回填 2. [重要语义] DROP COLUMN 是软删除, 数据仍留在行内; 重新 ADD 同名列会"复活"老行数据 这解释了为什么改列名(删+加新名)后数据看似丢失, 但加回旧列名后又能读到 → 敏感数据无法靠删列来清除, 需要重建表/覆写 3. [风险] ORM 重开表会按 struct 强制同步 schema, 静默删除 struct 里没有的列 纯 core 视角活跃列=[_id No Name Age Score Salary Active DeptName Dept] 含 DeptName, 调用 UseTable[Emp] 后活跃列=[_id No Name Age Score Salary Active Dept], DeptName 被自动 DropField; 手工加过列的表被 ORM 打开就会"丢列"(数据仍在行内, 再加回同名列可复活) 【结论】总耗时 13m32s | 校验 87/87 通过 | 数据问题 3 项 主库保留: /Users/yl32940/Projects/TsDB2/demo/bench_10m/bench_10m.db (2257.5MB) | 探针库: /Users/yl32940/Projects/TsDB2/demo/bench_10m/bench_10m_probe.db (0.6MB) 可将上述 .db 交给 analyzer 审计