Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

faster distinct SERVER-796

  • Loading branch information...
commit 5b5d73a6529b95e47033e40dcebee01d9417ff7f 1 parent 45f8d67
@erh erh authored
View
20 db/dbcommands.cpp
@@ -1472,13 +1472,25 @@ namespace mongo {
set<BSONElement,BSONElementCmpWithoutField> map;
long long size = 0;
-
- auto_ptr<DBClientCursor> cursor = db.query( ns , query , 0 , 0 , &keyPattern );
- while ( cursor->more() ){
- BSONObj o = cursor->next();
+
+ auto_ptr<Cursor> cursor = QueryPlanSet(ns.c_str() , query , BSONObj() ).getBestGuess()->newCursor();
+ auto_ptr<CoveredIndexMatcher> matcher;
+ if ( ! query.isEmpty() )
+ matcher.reset( new CoveredIndexMatcher( query , cursor->indexKeyPattern() ) );
+
+ while ( cursor->ok() ){
+ if ( matcher.get() && ! matcher->matchesCurrent( cursor.get() ) ){
+ cursor->advance();
+ continue;
+ }
+
+ BSONObj o = cursor->current();
+ cursor->advance();
+
BSONElement e = o.getFieldDotted( key.c_str() );
if ( ! e.type() )
continue;
+
if ( map.insert( e ).second ){
size += o.objsize() + 20;
uassert( 10044 , "distinct too big, 4mb cap" , size < 4 * 1024 * 1024 );
View
4 db/matcher.cpp
@@ -153,6 +153,10 @@ namespace mongo {
);
}
+
+ bool CoveredIndexMatcher::matchesCurrent( Cursor * cursor , MatchDetails * details ){
+ return matches( cursor->currKey() , cursor->currLoc() , details );
+ }
bool CoveredIndexMatcher::matches(const BSONObj &key, const DiskLoc &recLoc , MatchDetails * details ) {
if ( details )
View
4 db/matcher.h
@@ -24,7 +24,8 @@
#include <pcrecpp.h>
namespace mongo {
-
+
+ class Cursor;
class CoveredIndexMatcher;
class Matcher;
@@ -190,6 +191,7 @@ namespace mongo {
CoveredIndexMatcher(const BSONObj &pattern, const BSONObj &indexKeyPattern);
bool matches(const BSONObj &o){ return _docMatcher.matches( o ); }
bool matches(const BSONObj &key, const DiskLoc &recLoc , MatchDetails * details = 0 );
+ bool matchesCurrent( Cursor * cursor , MatchDetails * details = 0 );
bool needRecord(){ return _needRecord; }
Matcher& docMatcher() { return _docMatcher; }
View
5 db/queryoptimizer.cpp
@@ -451,6 +451,11 @@ namespace mongo {
b.append( "allPlans", arr );
return b.obj();
}
+
+ QueryPlanSet::PlanPtr QueryPlanSet::getBestGuess() const {
+ assert( plans_.size() );
+ return plans_[0];
+ }
QueryPlanSet::Runner::Runner( QueryPlanSet &plans, QueryOp &op ) :
op_( op ),
View
7 db/queryoptimizer.h
@@ -117,6 +117,10 @@ namespace mongo {
// a QueryOp on these plans.
class QueryPlanSet {
public:
+
+ typedef boost::shared_ptr< QueryPlan > PlanPtr;
+ typedef vector< PlanPtr > PlanSet;
+
QueryPlanSet( const char *ns,
const BSONObj &query,
const BSONObj &order,
@@ -133,10 +137,9 @@ namespace mongo {
const FieldRangeSet &fbs() const { return fbs_; }
BSONObj explain() const;
bool usingPrerecordedPlan() const { return usingPrerecordedPlan_; }
+ PlanPtr getBestGuess() const;
private:
void addOtherPlans( bool checkFirst );
- typedef boost::shared_ptr< QueryPlan > PlanPtr;
- typedef vector< PlanPtr > PlanSet;
void addPlan( PlanPtr plan, bool checkFirst ) {
if ( checkFirst && plan->indexKey().woCompare( plans_[ 0 ]->indexKey() ) == 0 )
return;
View
4 jstests/distinct_speed1.js
@@ -20,3 +20,7 @@ for ( i=0; i<3; i++ ){
print( "it: " + Date.timeFunc( fast ) );
print( "di: " + Date.timeFunc( slow ) );
}
+
+
+t.ensureIndex( { x : 1 } );
+t.distinct( "x" , { x : 5 } )
Please sign in to comment.
Something went wrong with that request. Please try again.