Skip to content

Commit dea9bbb

Browse files
docs(plan): section 4c dropped on measurement (1% ceiling); the published PK baseline measures the raw posture
Steps 1+2 of the agreed sequence: fresh comparative baseline + attribution on the ACCEPTANCE UPDATE shape. 4c (skip index maintenance when the indexed value is unchanged) is dead on that workload: - with idx_docs_name 74,016 ops/s - without the index entirely 73,209 ops/s -> 1.01x, i.e. a ~1% ceiling - WritePathProfiler profile only row-locate recorded; index-maint never fires on the batch path The --pk UPDATE never changes name/id, so every index-maintenance call there IS unchanged-value work: the premise held, the size of the prize did not. Per-row figures quoted for 4c do not describe this workload. The same run found something bigger: the harness has been publishing the RAW posture. BuildConfig(engine) defaults to NoEncryptMode=true, so the --pk comparison measured plaintext files (UPDATE 234,394) while the product default is at-rest records (74,016 on the same shape: 50K rows, 10K UPDATE by PK) against SQLite's 279,003. The honest UPDATE gap is therefore ~3.8x, not the ~1.2x the report suggests. The tax is not the overflow arena: a fixed-size-only table shows 0.40x (at-rest/raw) versus 0.34x with TEXT, so it is the per-record GCM work itself. Next measurement task (not started): make the --pk runner report both postures (section 0.1-6 requires the NoEncryptMode column anyway) and attribute the GCM cost - per-record nonce generation / cipher instance versus raw AES throughput. Gate: SharpCoreDB.slnx 0 errors; SharpCoreDB.Tests 1848 total / 0 failed / 16 skipped. No product code changed.
1 parent 4ff03bc commit dea9bbb

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

docs/performance/INSERT_UPDATE_PERFORMANCE_PLAN.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,40 @@ column's value, that maintenance is pure overhead.
809809
- **Evidence to collect first:** the §2 per-stage instrumentation will say whether this is 5% or 40%
810810
of the update cost. Do not do this before the instrumentation exists.
811811

812+
**Verdict (2026-09-14): dropped — the premise does not hold on the acceptance workload.** The `--pk` UPDATE
813+
workload is `UPDATE docs SET score = <new> WHERE id = <pk>` on a table whose only explicit index is
814+
`idx_docs_name ON docs(name)`, and that update never changes `name` or `id` — so every index-maintenance call
815+
there *is* work for an unchanged value, i.e. exactly §4c's case. Two independent measurements on that shape
816+
(50K rows, 10K updates by PK, single batch transaction):
817+
818+
| measurement | result |
819+
|---|---|
820+
| with `idx_docs_name` | 74,016 ops/s |
821+
| **without the index at all** (the ceiling §4c could reclaim) | 73,209 ops/s → **1.01×** |
822+
| `WritePathProfiler` stage profile | only `row-locate` recorded; `index-maint` never fires on the batch path |
823+
824+
Removing the index completely moves throughput by ~1%, so the ceiling for "skip unchanged-value maintenance"
825+
is 1% here — and §2's instrumentation is not wired into the batch UPDATE path at all, so the per-row figures
826+
quoted earlier do not describe this workload. Not worth the risk, and not to be re-attempted without a shape
827+
where index maintenance actually dominates (many indexes, high-cardinality updates).
828+
829+
**The same run established something bigger than §4c: the published comparison measures the wrong posture.**
830+
The at-rest posture costs ~2.5–2.9× on this exact workload, and the `--pk` harness has been reporting the
831+
**raw** posture, because `BuildConfig(engine)` defaults to `NoEncryptMode = true`:
832+
833+
| arm (50K rows, 10K UPDATE by PK, same machine, same shape) | UPDATE ops/s |
834+
|---|---:|
835+
| SharpCoreDB, `NoEncryptMode = true` — what the harness publishes | 217,456 (harness arm: 234,394) |
836+
| SharpCoreDB, product default (at-rest records) | **74,016** |
837+
| SQLite reference | 279,003 |
838+
839+
So the honest UPDATE gap is **~3.8× slower than SQLite in the default posture**, not the ~1.2× the raw arm
840+
suggests. The tax survives on a fixed-size-only table (0.40× vs 0.34× with TEXT), which rules out the overflow
841+
arena and points at the per-record GCM work itself. §0.1-6 already requires every target to carry the
842+
`NoEncryptMode` column beside it — the `--pk` runner does not, so making it report both postures, and
843+
attributing the GCM cost (per-record nonce generation / cipher instance vs raw AES throughput), is the next
844+
measurement task.
845+
812846
---
813847

814848
## 5. Phase 3 — INSERT: from competitive to ahead

0 commit comments

Comments
 (0)