diff options
author | Aaron <aaron@10gen.com> | 2012-04-02 15:59:45 -0700 |
---|---|---|
committer | Aaron <aaron@10gen.com> | 2012-04-06 21:48:54 -0700 |
commit | 7cacde89bb37051549b38abaf4d6b591b199b243 (patch) | |
tree | c69ba14ff6fc25bbdcc0df64ff08560fcc0cacb5 /src/mongo/db/queryoptimizer.cpp | |
parent | 2a447b7e4ffc1ee408d2c9376114fbcb97b5133f (diff) | |
download | mongo-7cacde89bb37051549b38abaf4d6b591b199b243.tar.gz |
SERVER-5063 $in limit efficiency.
Diffstat (limited to 'src/mongo/db/queryoptimizer.cpp')
-rw-r--r-- | src/mongo/db/queryoptimizer.cpp | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/src/mongo/db/queryoptimizer.cpp b/src/mongo/db/queryoptimizer.cpp index 00e88637699..bab670342de 100644 --- a/src/mongo/db/queryoptimizer.cpp +++ b/src/mongo/db/queryoptimizer.cpp @@ -241,7 +241,9 @@ doneCheckOrder: return shared_ptr<Cursor>( BtreeCursor::make( _d, _idxNo, *_index, _frv->startKey(), _frv->endKey(), true, _direction >= 0 ? 1 : -1 ) ); } else { - return shared_ptr<Cursor>( BtreeCursor::make( _d, _idxNo, *_index, _frv, _direction >= 0 ? 1 : -1 ) ); + return shared_ptr<Cursor>( BtreeCursor::make( _d, _idxNo, *_index, _frv, + independentRangesSingleIntervalLimit(), + _direction >= 0 ? 1 : -1 ) ); } } @@ -313,6 +315,56 @@ doneCheckOrder: } } } + + int QueryPlan::independentRangesSingleIntervalLimit() const { + if ( _scanAndOrderRequired && + _parsedQuery && + !_parsedQuery->wantMore() && + !isMultiKey() && + queryFiniteSetOrderSuffix() ) { + verify( 16111, _direction == 0 ); + // Limit the results for each compound interval. SERVER-5063 + return _parsedQuery->getSkip() + _parsedQuery->getNumToReturn(); + } + return 0; + } + + bool QueryPlan::queryFiniteSetOrderSuffix() const { + if ( !indexed() ) { + return false; + } + if ( !_frs.simpleFiniteSet() ) { + return false; + } + BSONObj idxKey = indexKey(); + BSONObjIterator index( idxKey ); + BSONObjIterator order( _order ); + int coveredNonUniversalRanges = 0; + while( index.more() ) { + if ( _frs.range( (*index).fieldName() ).universal() ) { + break; + } + ++coveredNonUniversalRanges; + if ( order.more() && str::equals( (*index).fieldName(), (*order).fieldName() ) ) { + ++order; + } + ++index; + } + if ( coveredNonUniversalRanges != _frs.numNonUniversalRanges() ) { + return false; + } + while( index.more() && order.more() ) { + if ( !str::equals( (*index).fieldName(), (*order).fieldName() ) ) { + return false; + } + if ( ( elementDirection( *index ) < 0 ) != ( elementDirection( *order ) < 0 ) ) { + return false; + } + ++order; + ++index; + } + return !order.more(); + } /** * @return a copy of the inheriting class, which will be run with its own @@ -334,7 +386,8 @@ doneCheckOrder: string QueryPlan::toString() const { return BSON( "index" << indexKey() << - "frv" << ( _frv ? _frv->toString() : "" ) + "frv" << ( _frv ? _frv->toString() : "" ) << + "order" << _order ).jsonString(); } |