Skip to content

fix: make HasProfileData an existence probe instead of a full-table scan - #6402

Open
javicj wants to merge 1 commit into
parca-dev:mainfrom
javicj:fix/hasprofiledata-full-table-scan
Open

fix: make HasProfileData an existence probe instead of a full-table scan#6402
javicj wants to merge 1 commit into
parca-dev:mainfrom
javicj:fix/hasprofiledata-full-table-scan

Conversation

@javicj

@javicj javicj commented Sep 4, 2026

Copy link
Copy Markdown

What does this PR do?

HasProfileData delegated to ProfileTypes with a zero time range. ProfileTypes
skips its time filter when start and end are zero, so every call executed:

SELECT DISTINCT name, sample_type, sample_unit, period_type, period_unit, (duration > 0)
FROM <table>

with no WHERE and no LIMIT — and the result was immediately reduced to
len(types) > 0. DISTINCT cannot terminate early, so this scanned the entire
table on every call just to answer a boolean. HasProfileData backs the UI's
empty-state check and runs on every page load; with hundreds of millions of rows
this made the UI landing screen take seconds to minutes.

This replaces it with SELECT 1 FROM <table> LIMIT 1, which reads one granule
and stops. Semantics are unchanged: both answer "does the table contain at
least one row", since any row necessarily has profile-type values (non-nullable
columns).

Why is it needed?

Observed in production with ~426M rows: the empty-state check was the single
most expensive query hitting ClickHouse, and under load it held connection
pool slots long enough to starve all other queries.

How to test it?

  • go test ./pkg/clickhouse/
  • Manually: with data in the store, the UI shows the explorer instead of the
    "no data yet" prompt; with an empty store, the prompt still shows. The
    response is now immediate regardless of table size.

HasProfileData delegated to ProfileTypes with a zero time range, which
skips the time filter and runs a DISTINCT over every row in the table,
only for the result to be reduced to a boolean. A LIMIT 1 probe returns
the same answer after reading a single granule. HasProfileData backs the
UI's empty-state check and runs on every page load.
@javicj
javicj requested a review from a team as a code owner September 4, 2026 14:44
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