libstore: drop redundant IndexReferrer index on Refs table#15439
Open
randomizedcoder wants to merge 2 commits intoNixOS:masterfrom
Open
libstore: drop redundant IndexReferrer index on Refs table#15439randomizedcoder wants to merge 2 commits intoNixOS:masterfrom
randomizedcoder wants to merge 2 commits intoNixOS:masterfrom
Conversation
The IndexReferrer index on Refs(referrer) is fully redundant with
sqlite_autoindex_Refs_1 on Refs(referrer, reference) — SQLite's
leftmost-prefix optimization means the composite primary key index
already serves all single-column lookups on the referrer column.
EXPLAIN QUERY PLAN confirms identical plans with and without the index
for all 6 Refs-related queries (QueryReferences, QueryReferrers,
DeleteSelfRefs trigger, etc.). The query planner never selects
IndexReferrer.
The practical benefits are modest:
- ~10 MB freed on a 131 MB database (~70k Refs entries)
- ~3-4% write-path improvement at scale (one fewer B-tree to maintain
per INSERT/DELETE), measured via Google Benchmark at N=100k
- No read-path impact (confirmed by both EXPLAIN QUERY PLAN and
benchmarks)
This introduces a schema migration ("20260309-drop-redundant-indexreferrer")
that drops the index on existing databases at next open. This is my first
time contributing a Nix database schema change, so maintainer review of
the migration approach is appreciated — the change itself is low-risk
(dropping an unused index is a no-op for correctness) but I want to make
sure it follows project conventions.
Also adds sqlite-interactive to the dev shell for convenient EXPLAIN
QUERY PLAN analysis, and a new refs-index-bench.cc benchmark for A/B
comparison of Refs table operations with and without the index.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Drop the redundant
IndexReferrerindex onRefs(referrer)to reduce database size and improve write performance.The
IndexReferrerindex is fully redundant withsqlite_autoindex_Refs_1onRefs(referrer, reference)— SQLite's leftmost-prefix optimization means the composite primary key index already serves all single-column lookups on thereferrercolumn. EXPLAIN QUERY PLAN confirms identical plans with and without the index for all 6 Refs-related queries. The query planner never selectsIndexReferrer.The practical benefits are modest:
Context
EXPLAIN QUERY PLAN output is identical with and without the index:
Note that
sqlite_autoindex_Refs_1is used as a covering index forreferrer=?lookups — it contains all the columns needed to satisfy the query without touching the table, making the separateIndexReferrerstrictly redundant.Changes
src/libstore/schema.sqlIndexReferrerfrom schemasrc/libstore/local-store.cc"20260309-drop-redundant-indexreferrer"to drop the index on existing databasespackaging/dev-shell.nixsqlite-interactiveto dev shell for EXPLAIN QUERY PLAN analysissrc/libstore-tests/refs-index-bench.ccsrc/libstore-tests/meson.buildSchema migration note
This introduces a schema migration that drops the index on existing databases at next open. This is my first time contributing a Nix database schema change, so maintainer review of the migration approach is appreciated — the change itself is low-risk (dropping an unused index is a no-op for correctness) but I want to make sure it follows project conventions.
Benchmark results (N=100k, 3 repetitions)
Write path (CPU time, mean):
Read path (CPU time, mean):
Mixed path (10:2 write:read ratio, CPU time, mean):
Verified on a live system
nix path-info,nix-store -q --references/--referrers,nix-store --verifyall work correctlyAdd 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.