diff --git a/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java b/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java --- a/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java +++ b/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java @@ -98,9 +98,11 @@ class StoreScanner extends NonLazyKeyValueScanner // Seek all scanners to the start of the Row (or if the exact matching row // key does not exist, then to the start of the next matching Row). + // Always check bloom filter to optimize the top row seek for delete + // family marker. if (explicitColumnQuery && lazySeekEnabledGlobally) { for (KeyValueScanner scanner : scanners) { - scanner.requestSeek(matcher.getStartKey(), false, useRowColBloom); + scanner.requestSeek(matcher.getStartKey(), false, true); } } else { for (KeyValueScanner scanner : scanners) { diff --git a/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java b/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java --- a/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java +++ b/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java @@ -76,7 +76,7 @@ public class ScanQueryMatcher { this.rowComparator = rowComparator; this.deletes = new ScanDeleteTracker(); this.stopRow = scan.getStopRow(); - this.startKey = KeyValue.createFirstOnRow(scan.getStartRow()); + this.startKey = KeyValue.createFirstOnRow(scan.getStartRow(), family, null); this.filter = scan.getFilter(); this.retainDeletesInOutput = retainDeletesInOutput; diff --git a/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java b/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java --- a/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java +++ b/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java @@ -50,6 +50,11 @@ class StoreFileScanner implements KeyValueScanner { private boolean delayedReseek; private KeyValue delayedSeekKV; + //The variable, realSeekDone, may cheat on store file scanner for the + // multi-column bloom-filter optimization. + // So this flag shows whether this storeFileScanner could do a reseek. + private boolean isReseekable = false; + private static final AtomicLong seekCount = new AtomicLong(); /** @@ -108,6 +113,8 @@ class StoreFileScanner implements KeyValueScanner { close(); return false; } + + this.isReseekable = true; cur = hfs.getKeyValue(); return true; } finally { @@ -269,7 +276,7 @@ class StoreFileScanner implements KeyValueScanner { if (realSeekDone) return; - if (delayedReseek) { + if (delayedReseek && this.isReseekable) { reseek(delayedSeekKV); } else { seek(delayedSeekKV);