diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-11-16 16:11:43 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-11-16 16:11:43 -0500 |
commit | 2603a9632c21f9e56e780f57b15313ed9d8810ff (patch) | |
tree | bd576ef14dab3a10f05a72edeef4837e1b448d20 /db | |
parent | 778d26e20c75ade65dc8b3a57d60d61651947df6 (diff) | |
download | mongo-2603a9632c21f9e56e780f57b15313ed9d8810ff.tar.gz |
use data from indexes if possivle SERVER-192
Diffstat (limited to 'db')
-rw-r--r-- | db/clientcursor.h | 7 | ||||
-rw-r--r-- | db/query.cpp | 41 |
2 files changed, 39 insertions, 9 deletions
diff --git a/db/clientcursor.h b/db/clientcursor.h index 98cbdd8f7c2..97490b3b1fa 100644 --- a/db/clientcursor.h +++ b/db/clientcursor.h @@ -218,6 +218,9 @@ namespace mongo { void setPos( int n ) { _pos = n; } // TODO : this is bad too BSONObj indexKeyPattern() { return _c->indexKeyPattern(); } + bool modifiedKeys() const { return _c->modifiedKeys(); } + bool isMultiKey() const { return _c->isMultiKey(); } + bool ok() { return _c->ok(); } bool advance(){ return _c->advance(); } BSONObj current() { return _c->current(); } @@ -354,8 +357,8 @@ namespace mongo { ElapsedTracker _yieldSometimesTracker; public: - shared_ptr< ParsedQuery > pq; - shared_ptr< Projection > fields; // which fields query wants returned + shared_ptr<ParsedQuery> pq; + shared_ptr<Projection> fields; // which fields query wants returned Message originalMessage; // this is effectively an auto ptr for data the matcher points to diff --git a/db/query.cpp b/db/query.cpp index 7de5aa4f089..09afa14a4b2 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -290,7 +290,7 @@ namespace mongo { int resultFlags = ResultFlag_AwaitCapable; int start = 0; int n = 0; - + if ( !cc ) { log() << "getMore: cursorid not found " << ns << " " << cursorid << endl; cursorid = 0; @@ -312,6 +312,10 @@ namespace mongo { c->checkLocation(); DiskLoc last; + scoped_ptr<Projection::KeyOnly> keyFieldsOnly; + if ( cc->modifiedKeys() == false && cc->isMultiKey() == false && cc->fields ) + keyFieldsOnly.reset( cc->fields->checkKey( cc->indexKeyPattern() ) ); + while ( 1 ) { if ( !c->ok() ) { if ( c->tailable() ) { @@ -350,11 +354,17 @@ namespace mongo { } else { last = c->currLoc(); - BSONObj js = c->current(); - - // show disk loc should be part of the main query, not in an $or clause, so this should be ok - fillQueryResultFromObj(b, cc->fields.get(), js, ( cc->pq.get() && cc->pq->showDiskLoc() ? &last : 0)); n++; + + if ( keyFieldsOnly ){ + fillQueryResultFromObj(b, 0, keyFieldsOnly->hydrate( c->currKey() ) ); + } + else { + BSONObj js = c->current(); + // show disk loc should be part of the main query, not in an $or clause, so this should be ok + fillQueryResultFromObj(b, cc->fields.get(), js, ( cc->pq.get() && cc->pq->showDiskLoc() ? &last : 0)); + } + if ( ( ntoreturn && n >= ntoreturn ) || b.len() > MaxBytesToReturnToClientAtOnce ){ c->advance(); cc->incPos( n ); @@ -547,7 +557,8 @@ namespace mongo { b << "cursor" << c->toString() << "indexBounds" << c->prettyIndexBounds(); b.done(); } - void noteScan( Cursor *c, long long nscanned, long long nscannedObjects, int n, bool scanAndOrder, int millis, bool hint, int nYields , int nChunkSkips ) { + void noteScan( Cursor *c, long long nscanned, long long nscannedObjects, int n, bool scanAndOrder, + int millis, bool hint, int nYields , int nChunkSkips , bool indexOnly ) { if ( _i == 1 ) { _c.reset( new BSONArrayBuilder() ); *_c << _b->obj(); @@ -570,6 +581,7 @@ namespace mongo { *_b << "nYields" << nYields; *_b << "nChunkSkips" << nChunkSkips; *_b << "isMultiKey" << c->isMultiKey(); + *_b << "indexOnly" << indexOnly; *_b << "indexBounds" << c->prettyIndexBounds(); @@ -640,6 +652,15 @@ namespace mongo { } else { _c = qp().newCursor( DiskLoc() , _pq.getNumToReturn() + _pq.getSkip() ); _capped = _c->capped(); + + cout << "ELIOT : " << _pq.getFields() << endl; + + // setup check for if we can only use index to extract + if ( _c->modifiedKeys() == false && _c->isMultiKey() == false && _pq.getFields() ){ + cout << "\t YO" << endl; + _keyFieldsOnly.reset( _pq.getFields()->checkKey( _c->indexKeyPattern() ) ); + cout << "\t " << _keyFieldsOnly.get() << endl; + } } if ( qp().scanAndOrderRequired() ) { @@ -763,6 +784,9 @@ namespace mongo { bb.appendKeys( _c->indexKeyPattern() , _c->currKey() ); bb.done(); } + else if ( _keyFieldsOnly ){ + fillQueryResultFromObj( _buf , 0 , _keyFieldsOnly->hydrate( _c->currKey() ) ); + } else { BSONObj js = _c->current(); assert( js.isValid() ); @@ -824,7 +848,9 @@ namespace mongo { } if ( _pq.isExplain() ) { - _eb.noteScan( _c.get(), _nscanned, _nscannedObjects, _n, scanAndOrderRequired(), _curop.elapsedMillis(), useHints && !_pq.getHint().eoo(), _nYields , _nChunkSkips); + _eb.noteScan( _c.get(), _nscanned, _nscannedObjects, _n, scanAndOrderRequired(), + _curop.elapsedMillis(), useHints && !_pq.getHint().eoo(), _nYields , + _nChunkSkips, _keyFieldsOnly.get() > 0 ); } else { if ( _buf.len() ) { @@ -883,6 +909,7 @@ namespace mongo { private: BufBuilder _buf; const ParsedQuery& _pq; + scoped_ptr<Projection::KeyOnly> _keyFieldsOnly; long long _ntoskip; long long _nscanned; |