mirror of
https://github.com/apache/druid.git
synced 2025-02-13 05:25:11 +00:00
Implemented Clint's recommendations
This commit is contained in:
parent
07503ea5c0
commit
287a367f41
@ -159,7 +159,7 @@ The Scan query currently supports ordering based on timestamp for non-legacy que
|
|||||||
will yield results that do not indicate which segment rows are from (`segmentId` will show up as `null`). Furthermore,
|
will yield results that do not indicate which segment rows are from (`segmentId` will show up as `null`). Furthermore,
|
||||||
time ordering is only supported where the result set limit is less than `druid.query.scan.maxRowsQueuedForOrdering`
|
time ordering is only supported where the result set limit is less than `druid.query.scan.maxRowsQueuedForOrdering`
|
||||||
rows **or** all segments scanned have fewer than `druid.query.scan.maxSegmentPartitionsOrderedInMemory` partitions. Also,
|
rows **or** all segments scanned have fewer than `druid.query.scan.maxSegmentPartitionsOrderedInMemory` partitions. Also,
|
||||||
time ordering is not support for queries issued directly to historicals unless a list of segments is specified. The
|
time ordering is not supported for queries issued directly to historicals unless a list of segments is specified. The
|
||||||
reasoning behind these limitations is that the implementation of time ordering uses two strategies that can consume too
|
reasoning behind these limitations is that the implementation of time ordering uses two strategies that can consume too
|
||||||
much heap memory if left unbounded. These strategies (listed below) are chosen on a per-Historical basis depending on
|
much heap memory if left unbounded. These strategies (listed below) are chosen on a per-Historical basis depending on
|
||||||
query result set limit and the number of segments being scanned.
|
query result set limit and the number of segments being scanned.
|
||||||
|
@ -111,13 +111,18 @@ public class ScanQueryRunnerFactory implements QueryRunnerFactory<ScanResultValu
|
|||||||
return returnedRows;
|
return returnedRows;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Query segment spec must be an instance of MultipleSpecificSegmentSpec because segment descriptors need
|
||||||
|
// to be present for a 1:1 matching of intervals with query runners. The other types of segment spec condense
|
||||||
|
// the intervals (i.e. merge neighbouring intervals), eliminating the 1:1 relationship between intervals
|
||||||
|
// and query runners.
|
||||||
if (!(query.getQuerySegmentSpec() instanceof MultipleSpecificSegmentSpec)) {
|
if (!(query.getQuerySegmentSpec() instanceof MultipleSpecificSegmentSpec)) {
|
||||||
throw new UOE("Time-ordering on scan queries is only supported for queries with segment specs"
|
throw new UOE("Time-ordering on scan queries is only supported for queries with segment specs"
|
||||||
+ "of type MultipleSpecificSegmentSpec");
|
+ "of type MultipleSpecificSegmentSpec");
|
||||||
}
|
}
|
||||||
|
// Ascending time order for both descriptors and query runners by default
|
||||||
List<SegmentDescriptor> descriptorsOrdered =
|
List<SegmentDescriptor> descriptorsOrdered =
|
||||||
((MultipleSpecificSegmentSpec) query.getQuerySegmentSpec()).getDescriptors(); // Ascending time order
|
((MultipleSpecificSegmentSpec) query.getQuerySegmentSpec()).getDescriptors();
|
||||||
List<QueryRunner<ScanResultValue>> queryRunnersOrdered = Lists.newArrayList(queryRunners); // Ascending time order by default
|
List<QueryRunner<ScanResultValue>> queryRunnersOrdered = Lists.newArrayList(queryRunners);
|
||||||
|
|
||||||
if (query.getOrder().equals(ScanQuery.Order.DESCENDING)) {
|
if (query.getOrder().equals(ScanQuery.Order.DESCENDING)) {
|
||||||
descriptorsOrdered = Lists.reverse(descriptorsOrdered);
|
descriptorsOrdered = Lists.reverse(descriptorsOrdered);
|
||||||
@ -208,7 +213,8 @@ public class ScanQueryRunnerFactory implements QueryRunnerFactory<ScanResultValu
|
|||||||
Comparator<ScanResultValue> priorityQComparator = new ScanResultValueTimestampComparator(scanQuery);
|
Comparator<ScanResultValue> priorityQComparator = new ScanResultValueTimestampComparator(scanQuery);
|
||||||
|
|
||||||
if (scanQuery.getLimit() > Integer.MAX_VALUE) {
|
if (scanQuery.getLimit() > Integer.MAX_VALUE) {
|
||||||
throw new UOE("Limit of %,d rows not supported for priority queue strategy of time-ordering scan results",
|
throw new UOE(
|
||||||
|
"Limit of %,d rows not supported for priority queue strategy of time-ordering scan results",
|
||||||
scanQuery.getLimit()
|
scanQuery.getLimit()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -288,7 +294,8 @@ public class ScanQueryRunnerFactory implements QueryRunnerFactory<ScanResultValu
|
|||||||
// (3) Create a sequence of results from each runner in the group and flatmerge based on timestamp
|
// (3) Create a sequence of results from each runner in the group and flatmerge based on timestamp
|
||||||
// (4) Create a sequence of results from each runner group
|
// (4) Create a sequence of results from each runner group
|
||||||
// (5) Join all the results into a single sequence
|
// (5) Join all the results into a single sequence
|
||||||
return Sequences.concat(
|
Sequence<ScanResultValue> resultSequence =
|
||||||
|
Sequences.concat(
|
||||||
Sequences.map(
|
Sequences.map(
|
||||||
Sequences.simple(groupedRunners),
|
Sequences.simple(groupedRunners),
|
||||||
runnerGroup ->
|
runnerGroup ->
|
||||||
@ -307,9 +314,12 @@ public class ScanQueryRunnerFactory implements QueryRunnerFactory<ScanResultValu
|
|||||||
)).reverse()
|
)).reverse()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).limit(
|
|
||||||
((ScanQuery) (queryPlus.getQuery())).getLimit()
|
|
||||||
);
|
);
|
||||||
|
long limit = ((ScanQuery) (queryPlus.getQuery())).getLimit();
|
||||||
|
if (limit == Long.MAX_VALUE) {
|
||||||
|
return resultSequence;
|
||||||
|
}
|
||||||
|
return resultSequence.limit(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user