diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java index d3308cdfd6d7cfc..91dd2f585a6719d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java @@ -98,6 +98,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -944,24 +945,37 @@ public void computeSampleTabletIds() { } OlapTable olapTable = (OlapTable) desc.getTable(); - long selectedRows = 0; + long totalSampleRows = 0; + List selectedPartitionList = new ArrayList<>(); for (Long partitionId : selectedPartitionIds) { final Partition partition = olapTable.getPartition(partitionId); final MaterializedIndex selectedTable = partition.getIndex(selectedIndexId); selectedRows += selectedTable.getRowCount(); + selectedPartitionList.add(partitionId); } - if (tableSample.isPercent() && tableSample.getSampleValue() == 100) { - sampleTabletIds.clear(); - return; - } else if (tableSample.getSampleValue() > selectedRows) { - sampleTabletIds.clear(); - return; + selectedPartitionList.sort(Comparator.naturalOrder()); + + if (tableSample.isPercent()) { + if (tableSample.getSampleValue() == 100) { + sampleTabletIds.clear(); + return; + } + totalSampleRows = (long) Math.max(selectedRows * (tableSample.getSampleValue() / 100.0), 1); + } else { + if (tableSample.getSampleValue() > selectedRows) { + sampleTabletIds.clear(); + return; + } + totalSampleRows = tableSample.getSampleValue(); } long hitRows = 0; // The number of rows hit by the tablet - for (Long partitionId : selectedPartitionIds) { - final Partition partition = olapTable.getPartition(partitionId); + long partitionSeek = tableSample.getSeek() != -1 + ? tableSample.getSeek() : (long) (new SecureRandom().nextDouble() * selectedPartitionIds.size()); + for (int i = 0; i < selectedPartitionList.size(); i++) { + int seekPid = (int) ((i + partitionSeek) % selectedPartitionList.size()); + final Partition partition = olapTable.getPartition(selectedPartitionList.get(seekPid)); final MaterializedIndex selectedTable = partition.getIndex(selectedIndexId); List tablets = selectedTable.getTablets(); if (tablets.isEmpty()) { @@ -976,21 +990,23 @@ public void computeSampleTabletIds() { tableSample.getSampleValue() * (selectedTable.getRowCount() / selectedRows), 1); } - long seek = tableSample.getSeek() != -1 + long tabletSeek = tableSample.getSeek() != -1 ? tableSample.getSeek() : (long) (new SecureRandom().nextDouble() * tablets.size()); - for (int i = 0; i < tablets.size(); i++) { - int seekTid = (int) ((i + seek) % tablets.size()); + for (int j = 0; j < tablets.size(); j++) { + int seekTid = (int) ((j + tabletSeek) % tablets.size()); if (tablets.get(seekTid).getRowCount(true) == 0) { continue; } sampleTabletIds.add(tablets.get(seekTid).getId()); sampleRows -= tablets.get(seekTid).getRowCount(true); - hitRows += tablets.get(seekTid).getRowCount(true); if (sampleRows <= 0) { break; } } + if (hitRows > totalSampleRows) { + break; + } } LOG.debug("after computeSampleTabletIds, hitRows {}, selectedRows {}", hitRows, selectedRows); }