| name | query-plan-snapshot-cli |
|---|---|
| description | Use QueryPlanSnapshotCli to capture and compare RDF4J query plans, then assess likely performance improvements/regressions from execution verification and semantic plan diffs. Trigger when users ask about optimizer impact, query-plan drift, join algorithm changes, or query performance regressions in testsuites/benchmark. |
Use this skill to run reproducible query-plan captures, triage historical theme-query benchmark results, and classify likely regression/improvement signals.
- Capture raw benchmark output into a normalized result file when needed.
- Analyze the newest dated run against historical results.
- Drill into the fastest known runs for a specific theme/query.
- If needed, capture baseline/candidate plan snapshots and diff them semantically.
Result files live in:
core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/theme-query-benchmark-results
Normalize raw JMH output into a new result file:
pbpaste | scripts/theme-query-benchmark-results.sh capturescripts/theme-query-benchmark-results.sh capture raw-jmh.txt
Analyze only the queries that are more than 20% slower than history:
core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/theme-query-benchmark-results/analyze-theme-query-history.sh
Sort regressions from biggest to smallest:
core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/theme-query-benchmark-results/analyze-theme-query-history.sh --sort-regressions
Only print the top N regressions:
core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/theme-query-benchmark-results/analyze-theme-query-history.sh --top 10
Analyze every latest query, including current-run wins over previous best:
core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/theme-query-benchmark-results/analyze-theme-query-history.sh --all
Drill into the three fastest known runs for one theme/query and print optimized plan/query when present:
core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/theme-query-benchmark-results/analyze-theme-query-history.sh --theme PHARMA --query-index 10
Interpretation:
- Default mode: newest dated file only for the “latest” baseline; compares against all other
results-*.md, includingresults-develop.mdandresults-main-branch.md, but prints only queries where latest is more than 20% slower than historical best. --sort-regressions: flat regression list, biggest slowdown first.--top N: top N regressions only; implies regression sorting.--all: prints every latest query; if latest is a new best it prints how much faster it is than the previous best.- Query detail mode: top three runs sorted by score ascending; ties prefer richer files with plan/query content.
plan no | query yes: optimized query rendered, no physical plan block in that result file.plan no | query no: summary-only run or no per-query capture in that file.
Use this path when the goal is optimizer-loop work: find the fastest known plan/query for a theme/query, then compare new runs back to that history before touching production logic.
Theme regression/snapshot tests in core/sail/lmdb now support reusing a prepared LMDB store across runs.
- Enable persistent reuse:
-Drdf4j.lmdb.themeRegression.persistentStore.enabled=true
- Optional custom root directory:
-Drdf4j.lmdb.themeRegression.persistentStore.root=persistent-lmdb-theme-store
- Default root directory:
persistent-lmdb-theme-store
Behavior:
- If the store has expected
triples/data.mdbandvalues/data.mdbsizes (fromexpected-db-file-sizes.properties), tests reuse it and skip rebuild/ingest. - If sizes mismatch or the marker file is missing/invalid, tests rebuild the store, then refresh the expected-size file.
Example focused run:
mvn -o -Dmaven.repo.local=.m2_repo -pl core/sail/lmdb -Dtest=LmdbThemeQueryRegressionTest#socialMediaFiveCycleInterleavesValuesWithFollowsEdges -Drdf4j.lmdb.themeRegression.persistentStore.enabled=true test
Use this when you need semantic plan diffs between two controlled captures of the same query.
- Capture baseline run (main/reference commit).
- Capture candidate run (changed commit) with same query selector +
--query-id. - Produce semantic diff (
--compare-existing). - Interpret runtime + diff together.
Use wrapper (enforces pre-install and optional logging):
- Baseline:
./.codex/skills/query-plan-snapshot-cli/scripts/run_query_plan_snapshot.sh --log /tmp/qps-baseline.log -- --store memory --theme MEDICAL_RECORDS --query-index 0 --query-id med-q0
- Candidate:
./.codex/skills/query-plan-snapshot-cli/scripts/run_query_plan_snapshot.sh --log /tmp/qps-candidate.log -- --store memory --theme MEDICAL_RECORDS --query-index 0 --query-id med-q0 --compare-latest --diff-mode structure+estimates
- Compare existing snapshots explicitly:
mvn -o -Dmaven.repo.local=.m2_repo -pl testsuites/benchmark -DskipTests exec:java@query-plan-snapshot -Dexec.args="--compare-existing --query-id med-q0 --compare-indices 1,0 --no-interactive --diff-mode structure+estimates" | tee /tmp/qps-compare.log
- Summarize improvement/regression signal:
python3 ./.codex/skills/query-plan-snapshot-cli/scripts/interpret_query_plan_regression.py --baseline-log /tmp/qps-baseline.log --candidate-log /tmp/qps-candidate.log --comparison-log /tmp/qps-compare.log
averageMillisdown with stableresultCount: improvement signal.averageMillisup with stableresultCount: regression signal.actualResultSizes=diff: semantic/data-shape risk; perf conclusion low confidence.joinAlgorithms=difforstructure=diff: optimizer behavior changed; correlate with runtime delta.estimates=diffonly: model/statistics shift; validate with repeated runs.
For more detailed reading patterns and triage prompts, use references/workflow.md.