full_run.log 24 KB

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