mrhhsg commented on code in PR #68279:
URL: https://github.com/apache/doris/pull/68279#discussion_r4060811359
##########
be/src/storage/segment/segment_iterator.cpp:
##########
@@ -899,7 +899,15 @@ Status
SegmentIterator::_get_row_ranges_by_column_conditions() {
(!_opts.topn_filter_source_node_ids.empty() ||
!_opts.col_id_to_predicates.empty() ||
_opts.delete_condition_predicates->num_of_column_predicate() > 0 ||
!_common_expr_ctxs_push_down.empty())) {
- RowRanges condition_row_ranges =
RowRanges::create_single(_segment->num_rows());
+ // Start from the rows that are still alive instead of the whole
segment: the
+ // bitmap already carries the key range and index pruning, so anything
outside
+ // it cannot be pruned again. Starting from the whole segment would
make the
+ // zone map / bloom filter counters report rows that were pruned
earlier, e.g.
+ // a point lookup that already matched a single row reports the whole
segment
+ // as zone-map filtered.
+ RowRanges condition_row_ranges =
+
RowRanges::create_single(static_cast<int64_t>(_row_bitmap.minimum()),
+
static_cast<int64_t>(_row_bitmap.maximum()) + 1);
Review Comment:
Fixed in 6025c8177a6. The condition ranges are built from the whole segment
again, and each step (bloom filter, zone map, expr zone map) now counts only
the removed rows that are still set in `_row_bitmap`
(`roaring_bitmap_range_cardinality` over the condition ranges), so the counters
are exact for disjoint key ranges and sparse index results. Added
`DisjointKeyRangesOnlyCountAliveRows` (key ranges `{1}` and `{5000}`, predicate
`v = 5000`): `RowsStatsFiltered == 1`.
##########
regression-test/suites/query_profile/point_lookup_zone_map_profile.groovy:
##########
@@ -0,0 +1,68 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import org.apache.doris.regression.action.ProfileAction
+
+suite('point_lookup_zone_map_profile', 'nonConcurrent') {
+ sql 'DROP TABLE IF EXISTS point_lookup_zone_map_profile'
+ sql '''
+ CREATE TABLE point_lookup_zone_map_profile (
+ k INT NOT NULL,
+ v INT NOT NULL
+ ) DUPLICATE KEY(k)
+ DISTRIBUTED BY HASH(k) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "disable_auto_compaction" = "true"
+ )
+ '''
+ sql '''
+ INSERT INTO point_lookup_zone_map_profile
+ SELECT number, number FROM numbers("number" = "200000")
+ '''
+
+ sql 'set enable_profile=true'
+ sql 'set profile_level=2'
+
+ def profileAction = new ProfileAction(context)
+ def token = UUID.randomUUID().toString()
+
+ // The key range narrows the scan down to a single row, so the zone map has
+ // nothing left to prune and must not report the rest of the segment as
+ // filtered. The token only keeps the statement identifiable in the
profile.
+ sql """
+ SELECT COUNT(*) FROM point_lookup_zone_map_profile
+ WHERE k = 12345 AND v = 12345 AND '${token}' IS NOT NULL
+ """
+
+ def profile = profileAction
+ .getProfileBySql(token, ['RowsKeyRangeFiltered',
'RowsStatsFiltered'])
+ .toString()
+ logger.info("profile of ${token}: ${profile}")
+
+ def keyRangeFiltered = (profile =~
/RowsKeyRangeFiltered:\s*([^\n]+)/).collect { it[1].trim() }
+ def statsFiltered = (profile =~ /RowsStatsFiltered:\s*([^\n]+)/).collect {
it[1].trim() }
+ assertTrue(!keyRangeFiltered.isEmpty(), "no RowsKeyRangeFiltered in
profile: ${profile}")
+ assertTrue(!statsFiltered.isEmpty(), "no RowsStatsFiltered in profile:
${profile}")
+ assertTrue(keyRangeFiltered.any { it != '0' },
+ "the key range should have filtered rows: ${profile}")
+ statsFiltered.each {
+ assertEquals('0', it, "rows pruned by the key range must not be
counted again: ${profile}")
+ }
+
+ sql 'DROP TABLE IF EXISTS point_lookup_zone_map_profile'
Review Comment:
Removed the trailing DROP in 6025c8177a6.
--
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]