Repository: kylin Updated Branches: refs/heads/yang22-hbase1.x c33fa8c9d -> 7f82104e9 (forced update)
KYLIN-2290 minor improvements on limit Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/cdd945cb Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/cdd945cb Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/cdd945cb Branch: refs/heads/yang22-hbase1.x Commit: cdd945cbe3c6a3326967dda4623bb4f3df855ef1 Parents: ed497fe Author: Hongbin Ma <mahong...@apache.org> Authored: Fri Dec 16 16:28:18 2016 +0800 Committer: Hongbin Ma <mahong...@apache.org> Committed: Fri Dec 16 16:28:18 2016 +0800 ---------------------------------------------------------------------- .../apache/kylin/common/KylinConfigBase.java | 1 + .../kylin/cube/CubeCapabilityChecker.java | 5 ++ .../kylin/gridtable/GTScanRequestBuilder.java | 2 +- .../kylin/metadata/realization/SQLDigest.java | 4 +- .../apache/kylin/storage/StorageContext.java | 74 +++++++------------- .../storage/gtrecord/CubeScanRangePlanner.java | 9 +-- .../gtrecord/GTCubeStorageQueryBase.java | 1 - .../gtrecord/SequentialCubeTupleIterator.java | 6 +- .../apache/kylin/query/ITKylinQueryTest.java | 1 - .../org/apache/kylin/query/KylinTestBase.java | 7 +- .../kylin/storage/hbase/ITStorageTest.java | 2 +- .../apache/kylin/query/relnode/OLAPContext.java | 6 +- .../kylin/query/relnode/OLAPFilterRel.java | 2 +- .../kylin/query/relnode/OLAPLimitRel.java | 10 ++- .../storage/hbase/cube/v1/CubeStorageQuery.java | 2 +- .../cube/v1/SerializedHBaseTupleIterator.java | 2 +- .../coprocessor/endpoint/CubeVisitService.java | 7 +- 17 files changed, 62 insertions(+), 79 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java ---------------------------------------------------------------------- diff --git a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java index 9923bc1..a1c9050 100644 --- a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java +++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java @@ -782,6 +782,7 @@ abstract public class KylinConfigBase implements Serializable { return Boolean.valueOf(getOptional("kylin.query.skip-empty-segments", "true")); } + @Deprecated//Limit is good even it's large. This config is meaning less since we already have scan threshold public int getStoragePushDownLimitMax() { return Integer.parseInt(getOptional("kylin.query.max-limit-pushdown", "10000")); } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-cube/src/main/java/org/apache/kylin/cube/CubeCapabilityChecker.java ---------------------------------------------------------------------- diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeCapabilityChecker.java b/core-cube/src/main/java/org/apache/kylin/cube/CubeCapabilityChecker.java index 38faed9..c45144b 100644 --- a/core-cube/src/main/java/org/apache/kylin/cube/CubeCapabilityChecker.java +++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeCapabilityChecker.java @@ -120,6 +120,11 @@ public class CubeCapabilityChecker { return result; } + if (digest.limitPrecedesAggr) { + logger.info("Exclude cube " + cube.getName() + " because there's limit preceding aggregation"); + return result; + } + if (digest.isRawQuery && rootFactTable.equals(digest.factTable)) { result.influences.add(new CapabilityInfluence() { @Override http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-cube/src/main/java/org/apache/kylin/gridtable/GTScanRequestBuilder.java ---------------------------------------------------------------------- diff --git a/core-cube/src/main/java/org/apache/kylin/gridtable/GTScanRequestBuilder.java b/core-cube/src/main/java/org/apache/kylin/gridtable/GTScanRequestBuilder.java index f542de1..bcec1f4 100644 --- a/core-cube/src/main/java/org/apache/kylin/gridtable/GTScanRequestBuilder.java +++ b/core-cube/src/main/java/org/apache/kylin/gridtable/GTScanRequestBuilder.java @@ -36,7 +36,7 @@ public class GTScanRequestBuilder { private boolean allowStorageAggregation = true; private double aggCacheMemThreshold = 0; private int storageScanRowNumThreshold = Integer.MAX_VALUE;// storage should terminate itself when $storageScanRowNumThreshold cuboid rows are scanned, and throw exception. - private int storagePushDownLimit = Integer.MAX_VALUE;// storage can quit working when $toragePushDownLimit aggregated rows are produced. + private int storagePushDownLimit = Integer.MAX_VALUE;// storage can quit scanning safely when $toragePushDownLimit aggregated rows are produced. private long startTime = -1; private long timeout = -1; private String storageBehavior = null; http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-metadata/src/main/java/org/apache/kylin/metadata/realization/SQLDigest.java ---------------------------------------------------------------------- diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/realization/SQLDigest.java b/core-metadata/src/main/java/org/apache/kylin/metadata/realization/SQLDigest.java index 83fc05c..4780487 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/realization/SQLDigest.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/realization/SQLDigest.java @@ -59,10 +59,11 @@ public class SQLDigest { public List<TblColRef> sortColumns; public List<OrderEnum> sortOrders; public boolean isRawQuery; + public boolean limitPrecedesAggr; public SQLDigest(String factTable, TupleFilter filter, List<JoinDesc> joinDescs, Set<TblColRef> allColumns, // List<TblColRef> groupbyColumns, Set<TblColRef> subqueryJoinParticipants, Set<TblColRef> filterColumns, Set<TblColRef> metricColumns, // - List<FunctionDesc> aggregations, List<SQLCall> aggrSqlCalls, List<TblColRef> sortColumns, List<OrderEnum> sortOrders) { + List<FunctionDesc> aggregations, List<SQLCall> aggrSqlCalls, List<TblColRef> sortColumns, List<OrderEnum> sortOrders,boolean limitPrecedesAggr) { this.factTable = factTable; this.filter = filter; this.joinDescs = joinDescs; @@ -76,6 +77,7 @@ public class SQLDigest { this.sortColumns = sortColumns; this.sortOrders = sortOrders; this.isRawQuery = isRawQuery(); + this.limitPrecedesAggr = limitPrecedesAggr; } private boolean isRawQuery() { http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-storage/src/main/java/org/apache/kylin/storage/StorageContext.java ---------------------------------------------------------------------- diff --git a/core-storage/src/main/java/org/apache/kylin/storage/StorageContext.java b/core-storage/src/main/java/org/apache/kylin/storage/StorageContext.java index bc43a87..9ef59fd 100644 --- a/core-storage/src/main/java/org/apache/kylin/storage/StorageContext.java +++ b/core-storage/src/main/java/org/apache/kylin/storage/StorageContext.java @@ -34,43 +34,29 @@ import com.google.common.collect.Range; public class StorageContext { private static final Logger logger = LoggerFactory.getLogger(StorageContext.class); - public static final int DEFAULT_THRESHOLD = 1000000; - private String connUrl; private int threshold; - private int limit; - private int offset; - private int finalPushDownLimit; - private boolean hasSort; - private boolean acceptPartialResult; - - private boolean exactAggregation; - private boolean needStorageAggregation; - private boolean enableLimit; - private boolean enableCoprocessor; - - private AtomicLong totalScanCount; + private int limit = Integer.MAX_VALUE; + private int offset = 0; + private int finalPushDownLimit = Integer.MAX_VALUE; + private boolean hasSort = false; + private boolean acceptPartialResult = false; + + private boolean exactAggregation = false; + private boolean needStorageAggregation = false; + private boolean limitEnabled = false; + private boolean enableCoprocessor = false; + + private AtomicLong totalScanCount = new AtomicLong(); private Cuboid cuboid; - private boolean partialResultReturned; - - private Range<Long> reusedPeriod; + private boolean partialResultReturned = false; public StorageContext() { - this.threshold = DEFAULT_THRESHOLD; - this.limit = DEFAULT_THRESHOLD; - this.totalScanCount = new AtomicLong(); - this.cuboid = null; - this.hasSort = false; - - this.exactAggregation = false; - this.enableLimit = false; - this.enableCoprocessor = false; - - this.acceptPartialResult = false; - this.partialResultReturned = false; - this.finalPushDownLimit = Integer.MAX_VALUE; + this.threshold = KylinConfig.getInstanceFromEnv().getScanThreshold(); } + private Range<Long> reusedPeriod; + public String getConnUrl() { return connUrl; } @@ -92,11 +78,10 @@ public class StorageContext { } public void setLimit(int l) { - if (l > limit) { - //cases like : select price from (select * from kylin_sales limit 10) limit 5000 - logger.info("Setting limit to {} but in current olap context, the limit is already {}, won't apply", l, limit); + if (limit != Integer.MAX_VALUE) { + logger.warn("Setting limit to {} but in current olap context, the limit is already {}, won't apply", l, limit); } else { - this.limit = l; + limit = l; } } @@ -109,15 +94,11 @@ public class StorageContext { } public void enableLimit() { - this.enableLimit = true; + this.limitEnabled = true; } public boolean isLimitEnabled() { - return this.enableLimit; - } - - private int getStoragePushDownLimit() { - return this.isLimitEnabled() ? this.getOffset() + this.getLimit() : Integer.MAX_VALUE; + return this.limitEnabled; } public int getFinalPushDownLimit() { @@ -126,19 +107,16 @@ public class StorageContext { public void setFinalPushDownLimit(IRealization realization) { - //decide the final limit push down - int tempPushDownLimit = this.getStoragePushDownLimit(); - if (tempPushDownLimit == Integer.MAX_VALUE) { + if (this.getLimit() == Integer.MAX_VALUE) { return; } - int pushDownLimitMax = KylinConfig.getInstanceFromEnv().getStoragePushDownLimitMax(); + int tempPushDownLimit = this.getOffset() + this.getLimit(); + if (!realization.supportsLimitPushDown()) { - logger.info("Not enabling limit push down because cube storage type not supported"); - } else if (tempPushDownLimit > pushDownLimitMax) { - logger.info("Not enabling limit push down because the limit(including offset) {} is larger than kylin.query.max-limit-pushdown {}", // - tempPushDownLimit, pushDownLimitMax); + logger.warn("Not enabling limit push down because cube storage type not supported"); } else { + this.limitEnabled = true; this.finalPushDownLimit = tempPushDownLimit; logger.info("Enable limit: " + tempPushDownLimit); } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java ---------------------------------------------------------------------- diff --git a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java index 8d5a3d4..b05a629 100644 --- a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java +++ b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java @@ -148,15 +148,10 @@ public class CubeScanRangePlanner extends ScanRangePlannerBase { GTScanRequest scanRequest; List<GTScanRange> scanRanges = this.planScanRanges(); if (scanRanges != null && scanRanges.size() != 0) { - GTScanRequestBuilder builder = new GTScanRequestBuilder().setInfo(gtInfo).setRanges(scanRanges).setDimensions(gtDimensions).// + scanRequest = new GTScanRequestBuilder().setInfo(gtInfo).setRanges(scanRanges).setDimensions(gtDimensions).// setAggrGroupBy(gtAggrGroups).setAggrMetrics(gtAggrMetrics).setAggrMetricsFuncs(gtAggrFuncs).setFilterPushDown(gtFilter).// setAllowStorageAggregation(context.isNeedStorageAggregation()).setAggCacheMemThreshold(cubeSegment.getCubeInstance().getConfig().getQueryCoprocessorMemGB()).// - setStorageScanRowNumThreshold(context.getThreshold()); - - if (context.getFinalPushDownLimit() != Integer.MAX_VALUE) - builder.setStoragePushDownLimit(context.getFinalPushDownLimit()); - - scanRequest = builder.createGTScanRequest(); + setStoragePushDownLimit(context.getFinalPushDownLimit()).setStorageScanRowNumThreshold(context.getThreshold()).createGTScanRequest(); } else { scanRequest = null; } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/GTCubeStorageQueryBase.java ---------------------------------------------------------------------- diff --git a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/GTCubeStorageQueryBase.java b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/GTCubeStorageQueryBase.java index 9c74cca..85de844 100644 --- a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/GTCubeStorageQueryBase.java +++ b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/GTCubeStorageQueryBase.java @@ -383,7 +383,6 @@ public abstract class GTCubeStorageQueryBase implements IStorageQuery { } if (possible) { - context.enableLimit(); context.setFinalPushDownLimit(cubeInstance); } } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/SequentialCubeTupleIterator.java ---------------------------------------------------------------------- diff --git a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/SequentialCubeTupleIterator.java b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/SequentialCubeTupleIterator.java index bef0e88..3a64de7 100644 --- a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/SequentialCubeTupleIterator.java +++ b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/SequentialCubeTupleIterator.java @@ -46,7 +46,6 @@ public class SequentialCubeTupleIterator implements ITupleIterator { protected List<CubeSegmentScanner> scanners; protected List<SegmentCubeTupleIterator> segmentCubeTupleIterators; protected Iterator<ITuple> tupleIterator; - protected final int storagePushDownLimit; protected StorageContext context; private int scanCount; @@ -62,8 +61,7 @@ public class SequentialCubeTupleIterator implements ITupleIterator { segmentCubeTupleIterators.add(new SegmentCubeTupleIterator(scanner, cuboid, selectedDimensions, selectedMetrics, returnTupleInfo, context)); } - this.storagePushDownLimit = context.getFinalPushDownLimit(); - if (storagePushDownLimit == Integer.MAX_VALUE) { + if (!context.isLimitEnabled()) { //normal case tupleIterator = Iterators.concat(segmentCubeTupleIterators.iterator()); } else { @@ -75,7 +73,7 @@ public class SequentialCubeTupleIterator implements ITupleIterator { return input; } }); - tupleIterator = new SortedIteratorMergerWithLimit<ITuple>(transformed, storagePushDownLimit, segmentCubeTupleIterators.get(0).getCubeTupleConverter().getTupleDimensionComparator()).getIterator(); + tupleIterator = new SortedIteratorMergerWithLimit<ITuple>(transformed, context.getFinalPushDownLimit(), segmentCubeTupleIterators.get(0).getCubeTupleConverter().getTupleDimensionComparator()).getIterator(); } } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java ---------------------------------------------------------------------- diff --git a/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java b/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java index 0379bd5..98b294d 100644 --- a/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java +++ b/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java @@ -338,7 +338,6 @@ public class ITKylinQueryTest extends KylinTestBase { List<File> sqlFiles = getFilesFromFolder(new File(getQueryFolderPrefix() + "src/test/resources/query/sql_limit"), ".sql"); for (File sqlFile : sqlFiles) { runSQL(sqlFile, false, false); - assertTrue(checkLimitEnabled()); assertTrue(checkFinalPushDownLimit()); } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java ---------------------------------------------------------------------- diff --git a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java index 114a28d..b8a48ef 100644 --- a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java +++ b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java @@ -655,14 +655,9 @@ public class KylinTestBase { } - protected boolean checkLimitEnabled() { - OLAPContext context = getFirstOLAPContext(); - return (context.storageContext.isLimitEnabled()); - } - protected boolean checkFinalPushDownLimit() { OLAPContext context = getFirstOLAPContext(); - return (context.storageContext.getFinalPushDownLimit() != Integer.MAX_VALUE); + return context.storageContext.isLimitEnabled(); } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITStorageTest.java ---------------------------------------------------------------------- diff --git a/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITStorageTest.java b/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITStorageTest.java index db9d133..aea8bef 100644 --- a/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITStorageTest.java +++ b/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITStorageTest.java @@ -148,7 +148,7 @@ public class ITStorageTest extends HBaseMetadataTestCase { int count = 0; ITupleIterator iterator = null; try { - SQLDigest sqlDigest = new SQLDigest("default.test_kylin_fact", filter, null, Collections.<TblColRef> emptySet(), groups, Sets.<TblColRef> newHashSet(), Collections.<TblColRef> emptySet(), Collections.<TblColRef> emptySet(), aggregations, Collections.<SQLCall> emptyList(), new ArrayList<TblColRef>(), new ArrayList<SQLDigest.OrderEnum>()); + SQLDigest sqlDigest = new SQLDigest("default.test_kylin_fact", filter, null, Collections.<TblColRef> emptySet(), groups, Sets.<TblColRef> newHashSet(), Collections.<TblColRef> emptySet(), Collections.<TblColRef> emptySet(), aggregations, Collections.<SQLCall> emptyList(), new ArrayList<TblColRef>(), new ArrayList<SQLDigest.OrderEnum>(), false); iterator = storageEngine.search(context, sqlDigest, mockup.newTupleInfo(groups, aggregations)); while (iterator.hasNext()) { ITuple tuple = iterator.next(); http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/query/src/main/java/org/apache/kylin/query/relnode/OLAPContext.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPContext.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPContext.java index 8278fb0..dde98a6 100644 --- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPContext.java +++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPContext.java @@ -112,7 +112,9 @@ public class OLAPContext { public Set<OLAPTableScan> allTableScans = new HashSet<>(); public TupleInfo returnTupleInfo = null; public boolean afterAggregate = false; - public boolean afterSkippedFilter = false; + public boolean afterHavingClauseFilter = false; + public boolean afterLimit = false; + public boolean limitPrecedesAggr = false; public boolean afterJoin = false; public boolean hasJoin = false; @@ -148,7 +150,7 @@ public class OLAPContext { public SQLDigest getSQLDigest() { if (sqlDigest == null) - sqlDigest = new SQLDigest(firstTableScan.getTableName(), filter, joins, allColumns, groupByColumns, subqueryJoinParticipants, filterColumns, metricsColumns, aggregations, aggrSqlCalls, sortColumns, sortOrders); + sqlDigest = new SQLDigest(firstTableScan.getTableName(), filter, joins, allColumns, groupByColumns, subqueryJoinParticipants, filterColumns, metricsColumns, aggregations, aggrSqlCalls, sortColumns, sortOrders, limitPrecedesAggr); return sqlDigest; } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java index 411142d..1981c10 100755 --- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java +++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java @@ -302,7 +302,7 @@ public class OLAPFilterRel extends Filter implements OLAPRel { if (!context.afterAggregate) { translateFilter(context); } else { - context.afterSkippedFilter = true;//having clause is skipped + context.afterHavingClauseFilter = true;//having clause is skipped } } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java index f0af863..9ebdf60 100644 --- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java +++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java @@ -77,7 +77,9 @@ public class OLAPLimitRel extends SingleRel implements OLAPRel { this.columnRowType = buildColumnRowType(); this.context = implementor.getContext(); - if (!context.afterSkippedFilter) { + // ignore limit after having clause + // ignore limit after another limit, e.g. select A, count(*) from (select A,B from fact group by A,B limit 100) limit 10 + if (!context.afterHavingClauseFilter && !context.afterLimit) { Number limitValue = (Number) (((RexLiteral) localFetch).getValue()); int limit = limitValue.intValue(); this.context.storageContext.setLimit(limit); @@ -87,6 +89,12 @@ public class OLAPLimitRel extends SingleRel implements OLAPRel { int offset = offsetValue.intValue(); this.context.storageContext.setOffset(offset); } + + context.afterLimit = true; + + if (!this.context.afterAggregate) { + this.context.limitPrecedesAggr = true; + } } } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/CubeStorageQuery.java ---------------------------------------------------------------------- diff --git a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/CubeStorageQuery.java b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/CubeStorageQuery.java index 02aa64a..1b08880 100644 --- a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/CubeStorageQuery.java +++ b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/CubeStorageQuery.java @@ -764,8 +764,8 @@ public class CubeStorageQuery implements IStorageQuery { boolean goodFilter = filter == null || (TupleFilter.isEvaluableRecursively(filter) && context.isCoprocessorEnabled()); boolean goodSort = !context.hasSort(); if (goodAggr && goodFilter && goodSort) { - logger.info("Enable limit " + context.getLimit()); context.enableLimit(); + logger.info("Enable limit " + context.getLimit()); } } http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/SerializedHBaseTupleIterator.java ---------------------------------------------------------------------- diff --git a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/SerializedHBaseTupleIterator.java b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/SerializedHBaseTupleIterator.java index e8dd5b9..c4f7367 100644 --- a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/SerializedHBaseTupleIterator.java +++ b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v1/SerializedHBaseTupleIterator.java @@ -100,7 +100,7 @@ public class SerializedHBaseTupleIterator implements ITupleIterator { return true; // 1. check limit - if (context.isLimitEnabled() && scanCount >= context.getLimit() + context.getOffset()) { + if (context.isLimitEnabled() && (scanCount - context.getOffset() >= context.getLimit())) { return false; } // 2. check partial result http://git-wip-us.apache.org/repos/asf/kylin/blob/cdd945cb/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java ---------------------------------------------------------------------- diff --git a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java index da9c932..38efecc 100644 --- a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java +++ b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java @@ -254,14 +254,15 @@ public class CubeVisitService extends CubeVisitProtos.CubeVisitService implement @Override public boolean hasNext() { + counter++; + if (counter > scanReq.getStorageScanRowNumThreshold()) { - throw new GTScanExceedThresholdException("Exceed scan threshold at " + counter); + throw new GTScanExceedThresholdException("Exceed scan threshold at " + counter + ", consider increasing kylin.query.memory-budget-bytes and kylin.query.scan-threshold"); } if (counter % (10 * GTScanRequest.terminateCheckInterval) == 1) { - logger.info("Scanned " + counter + " rows from HBase."); + logger.info("scanning " + counter + "th row from HBase."); } - counter++; return allCellLists.hasNext(); }