gortiz opened a new issue, #18685:
URL: https://github.com/apache/pinot/issues/18685

   ## Summary
   
   For a selection query `... ORDER BY <identifier> [DESC] LIMIT n`, Pinot's 
single-stage engine uses `MinMaxValueBasedSelectionOrderByCombineOperator`, 
which skips a segment when its column min/max can't beat the current top-`n` 
boundary (so an unfiltered "latest n" query touches only a couple of segments). 
**Adding any filter predicate — even a trivially-true one on an unrelated 
column — silently defeats this optimization**, and the query falls back to 
scanning *all* segments.
   
   ## Environment
   
   - Apache Pinot `1.6.0-SNAPSHOT` (commit 
`dd6520c726761a6988107b96bfa41daf6617e522`)
   - OFFLINE table, single-stage engine (`SET useMultistageEngine=false`). The 
multi-stage engine shows the same behavior at the leaf stage.
   
   ## Reproduction
   
   Any multi-segment OFFLINE table works. Here: TPC-H `lineitem`, **600,037,902 
rows across 300 OFFLINE segments**, time column `l_ship_ts` (TIMESTAMP), data 
laid out so each segment covers a contiguous `l_ship_ts` range (tight 
per-segment min/max). Numbers are from the broker response.
   
   | # | query | `numSegmentsProcessed` | `numDocsScanned` | time |
   |---|---|---:|---:|---:|
   | 1 | `SELECT * FROM lineitem ORDER BY l_ship_ts DESC LIMIT 10` | **2** | 
281,125 | 143 ms |
   | 2 | `SELECT * FROM lineitem WHERE l_orderkey > 0 ORDER BY l_ship_ts DESC 
LIMIT 10` | **300** | 26,930,581 | 2,864 ms |
   | 3 | `SELECT * FROM lineitem WHERE l_ship_ts < CAST('1998-11-22 00:00:00' 
AS TIMESTAMP) ORDER BY l_ship_ts DESC LIMIT 10` | **299** | 28,812,078 | 2,569 
ms |
   
   - **#1 (no filter):** the min/max skip works — only 2 of 300 segments 
processed.
   - **#2 (trivially-true filter on a *different* column, matches every row):** 
300/300 segments, ~96× more rows scanned, ~20× slower. The predicate is 
semantically a no-op yet it disables the skip.
   - **#3 (keyset pagination):** same — 299/300 segments.
   
   ## Expected behavior
   
   The min/max segment-skip should remain valid in the presence of a filter. 
For descending order a segment is skipped when `segment.max(orderByCol) < 
boundary`; since the filtered rows are a subset of all rows, if the segment's 
(unfiltered) max is already below the current boundary then **no row — filtered 
or not — can enter the top-`n`**. So #2 and #3 should also process ~2 segments.
   
   ## Pointers
   
   - `CombinePlanNode#getCombineOperator` selects 
`MinMaxValueBasedSelectionOrderByCombineOperator` for `isSelectionQuery && 
limit > 0 && orderBy[0] is IDENTIFIER` — with **no filter guard** — so the 
operator *is* used for filtered queries.
   - `MinMaxValueBasedSelectionOrderByCombineOperator#processSegments` reads 
each segment's `DataSourceMetadata.getMin/MaxValue()` and skips via 
`segment.max < boundary` (DESC) once a segment returns `≥ limit + offset` rows. 
This skip logic does not reference the filter.
   
   So the operator is selected and the skip would be safe, yet a filter 
prevents the skip from engaging (the boundary is established — in #2 the newest 
segment returns 10 rows — but no segments are pruned). I have not pinned the 
exact root-cause line (boundary propagation / how the filtered per-segment 
results feed the combine); the behavior is fully reproducible via the 
trivial-filter case (#2).
   
   ## Impact
   
   Any "latest n matching rows" or keyset-pagination query with a predicate 
scans the whole table instead of a couple of segments (here 281K → 27M docs, 
143 ms → 2.9 s). Notably, deep `OFFSET` *without* a filter stays cheap, so 
adding a `WHERE` counter-intuitively makes a top-`n` query dramatically slower.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to