Diagnose a slow query
Everything here works with no API key and no model. That is the point: the console answers "why is this slow" from Lance's own plan and IO counters.
Run it and read the card
Query tab. Choose a mode, run it, and read the diagnosis:
RETURNED 10 TIME 1 ms READ 3.5 MB IOS 21 FRAGMENTS 1
brute-force vector scan — Every row's vector is read and compared. Exact, and
linear in table size.Three things worth reading in order:
The access path. brute-force vector scan, ANN index, inverted index,
scalar index. This comes from Lance's own plan, and it is the answer most of the
time — a search that reads megabytes on a small table is almost always a search that
found no index to use.
The bytes. Not an estimate. The handle's IO counters are drained before and after this query and nothing else.
The pushed-down filter. track = Utf8("Go") means rows were rejected while
reading rather than after, which is the difference between a filter that helps and
one that only tidies the output.
Press + plan for the raw plan. Lance owns that format, so the console shows what it recognised beside the real thing rather than pretending to parse all of it.
An index that exists and is not used
If a vector column has an index and the plan still says brute-force vector scan, the
console says why:
vectorhas an index built for l2, and this search asked for cosine. Lance cannot use the index for a different metric, so it scanned every row instead — the same answer at the cost the index exists to avoid.
Lance does not refuse a metric mismatch. It logs a line nobody reads and falls back to a full scan. Leaving the metric unset uses whatever the index was built with.
Hybrid, and where its cost goes
Hybrid runs full-text and vector as two legs and fuses them by rank. Each leg is costed on its own, because that is where the interesting fact lives:
fts 25 rows · 3 ms · 147,348 B · inverted index
vector 8 rows · 1 ms · 3,454,631 B · brute-force vector scanOne leg costs twenty-three times the other. Fusion is by rank, never by score: BM25 relevance and a vector distance are different quantities in different units, and one of them is better when it is larger.
Before and after
Compare tab. Pick two versions and run the same query against both. This is what turns "I built an index" into a number:
v1 could not run — Cannot perform full text search unless an INVERTED index exists
v2 25 rows · 1 ms · 135 KB · inverted indexA query one version cannot answer at all is a result, not an error — it is the clearest before-and-after there is. When both sides answer, the difference is stated in bytes and in whether the access path changed.
Both sides are pinned to explicit version numbers, so a dataset being written to while you look cannot give you a before from one moment and an after from another.
Take the answer with you
Every result carries + python — the script that reproduces it, generated from the spec that actually ran. Save the query itself from the same panel; it re-runs against whatever the table is now, which is the point of saving it.
Hand the whole thing to somebody
Under the result, and again at the foot of Insights, is a bundle. It collects what you have been reading — the schema, the versions, the layout, the findings with their evidence, the query and its plan, what each of them cost, and which Lance read them — into one document, and says what assembling it spent.
Two files, because two things happen to a diagnosis:
- markdown for an issue, a pull request, or a message. It is written to be read as it is.
- json for another console. Console → Open a bundle renders it with the same finding cards, from the file, with nothing uploaded.
Three things do not travel. The rows — the reproduction re-runs them against the
reader's own copy, which is the honest way to share a result. Credentials, dropped
by key wherever they appear. And the database root, replaced with <root> unless
you pass paths=kept, because a local path carries a username and a bucket carries an
employer, and a public issue is a poor place to find that out. The document records
which mode produced it and reports the scheme separately, so the substitution costs no
meaning.
From a terminal, and from an agent:
lancescope bundle segments > report.mdThe MCP tool is table_bundle, so an agent asked to write up what is wrong with a
table produces the same document rather than retyping the other tools' answers into
prose.