-
[OPIK-6884] [BE] perf: project/trace-id scope dataset-item + optimization enrichment scans (#7412)
发布于
2026-07-09 15:33:29 +00:00 - [OPIK-6884] [BE] perf: bound dataset-item filter-gate traces scans to the experiment trace-id set
Bucket-1 R3 residual from the OPIK-6883 full-scan audit. The DatasetItemDAO
experiment-item/feedback filter gates scanned the whole workspace's traces
(workspace_id only, all projects) to resolve the experiment items' trace ids.- Bound both gates (count and stats) by the referenced experiment trace-id set:
AND id IN (SELECT trace_id FROM experiment_items WHERE workspace_id = :workspace_id AND experiment_id IN :experimentIds). The set is implied by the existing
ei.trace_id = tfs.idjoin, so results are unchanged; it adds anid
primary-key condition. Prod EXPLAIN (large workspace): traces read drops
98,507 -> 1,309 granules (~75x). - Use
traces FINALin both gates:<experiment_item_filters>can filter
mutable trace columns, which must be matched against the deduplicated latest
version, not stale ReplacingMergeTree versions. FINAL is now affordable
because it is scoped to the same ~1,309 bounded granules (same I/O as the
priorLIMIT 1 BY, only a small bounded merge added); the now-redundant
LIMIT 1 BY idon the count gate is dropped.
OptimizationDAO.FIND (also flagged) was investigated and needs no change: it
scans only the small workspace-scopedoptimizationsentity table (not
traces/spans, so not a tiering concern), and project_id is not in its sorting
key(workspace_id, dataset_id, id), so a project predicate would not prune.Validated by DatasetsResourceTest$FindDatasetItemsWithExperimentItems (56 tests).
- perf(optimizations): project-scope the FIND duration/cost trace+span scans
OptimizationDAO.FIND's experiment_durations CTE enriches optimizations with
per-experiment duration/cost by scanning traces and spans for the experiments'
trace ids. Both were scoped by workspace_id + (trace_)id IN only, with no
project_id, so the (workspace_id, project_id, ...) sorting-key prefix couldn't
prune - the flagged "no target-project pruning" (R3/row 12, OPIK-6883).Add
AND project_id IN (SELECT DISTINCT project_id FROM traces WHERE workspace_id = :workspace_id AND id IN (SELECT trace_id FROM experiment_items_final))to both scans. A span/trace shares its trace's
project, so the resolved project set is a superset filter - results unchanged -
and it restores the PK-prefix prune. Prod EXPLAIN (large workspace): spans
4,842 -> 163 granules (~30x); traces also project-pruned.Validated by OptimizationsResourceTest GetOptimizerById + FindOptimizations
(13 tests).- perf(dataset-items): project-scope the filter-gate traces scans
Follow-up to the id-set bound: the DatasetItemDAO count/stats filter gates were
bounded byid IN (experiment trace-id set)but not by project, soid(the
3rd sort-key column) only did generic-exclusion pruning across all projects.
AddAND project_id IN (SELECT DISTINCT project_id FROM traces WHERE workspace_id = :workspace_id AND id IN (...))to both gates, enabling the full
(workspace_id, project_id, id) prefix (result-preserving: the traces are in the
resolved projects; also makes FINAL cheaper). Prod EXPLAIN: the same id set
drops from ~1,305 to ~54 granules (~24x further).Validated by DatasetsResourceTest$FindDatasetItemsWithExperimentItems (56 tests).
下载附件