Skip to content

[python] Add explain and profiling for local search - #9833

Open
TheR1sing3un wants to merge 8 commits into
apache:masterfrom
TheR1sing3un:codex/search-explain-profile
Open

TheR1sing3un wants to merge 8 commits into
apache:masterfrom
TheR1sing3un:codex/search-explain-profile

Conversation

@TheR1sing3un

@TheR1sing3un TheR1sing3un commented Sep 15, 2026

Copy link
Copy Markdown
Member

Purpose

Add explain() and opt-in profile() to local vector, batch vector, full-text, and hybrid search builders and multimodal queries. Users can inspect planned index coverage and raw fallback, then identify time spent in index search, filtering, refinement, fusion, and result lookup.

This branch includes the snapshot consistency fix from #9843. Each execution uses one read view across routes, filtering, raw fallback, and result lookup. Query reuse resolves a fresh snapshot, while explicit time-travel selectors remain effective. The fix can land independently before this feature.

explain() returns a structured, printable plan without running vector/text search. profile() executes once and returns the normal result together with the plan, stage timings, and counters:

query = docs.search(query_vector, column="embedding").limit(10)
print(query.explain())
report = query.profile()
neighbors = report.result
print(report.route_metrics)

Coverage uses unions of planned row-ID ranges and reports indexed/raw overlap; it does not estimate live rows or recall. Primary-key source-file coverage is reported as unavailable. Profiles preserve route order and hybrid concurrency, report actual lookup snapshot IDs, and keep timing/counter collection disabled for ordinary execution. Stage times are inclusive and can overlap. Index reader cleanup is shared across vector, batch, and full-text searches; profiled futures publish results only after cleanup and do not allow wrapper cancellation to close a running reader. Diagnostic planning does not separately parse or validate refinement options.

Document the APIs, result types, counter definitions, and measurement limits, including partial instrumentation of primary-key readers.

Tests

The latest full CI run passed, including Rust main 66f655b30a38: 5,230 tests passed, 124 skipped, and 2,250 native plans exercised.

After syncing with master and its incremental-read semantics, 399 passed and 47 skipped in the targeted Python 3.9 regression run:

  • Search diagnostics and snapshot regressions, including concurrent deletes/updates in normal and profiled vector/batch/hybrid queries, retained tag metadata through scan.version, query reuse, native indexed-vector lookup, and full-text live-row/raw reads.
  • All four PK index test modules, vector filters, hybrid execution/ranking, multimodal tables, time travel and table copies, incremental/expanded/native planner tests, scan modes, and split serialization.
  • Native cases requiring pypaimon_rust were skipped locally, along with optional full-text/Ray cases. Full Python matrix and Rust-main validation: https://github.com/apache/paimon/actions/runs/34991664130
  • Changed Python files pass repository-configured flake8; Python license headers and git diff --check pass.

@TheR1sing3un
TheR1sing3un marked this pull request as ready for review September 15, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant