Пример #1
0
    void QueryPlanSet::addOtherPlans( bool checkFirst ) {
        const char *ns = fbs_.ns();
        NamespaceDetails *d = nsdetails( ns );
        if ( !d )
            return;

        // If table scan is optimal or natural order requested
        if ( ( fbs_.nNontrivialBounds() == 0 && order_.isEmpty() ) ||
            ( !order_.isEmpty() && !strcmp( order_.firstElement().fieldName(), "$natural" ) ) ) {
            // Table scan plan
            addPlan( PlanPtr( new QueryPlan( fbs_, order_ ) ), checkFirst );
            return;
        }
        
        PlanSet plans;
        for( int i = 0; i < d->nIndexes; ++i ) {
            PlanPtr p( new QueryPlan( fbs_, order_, &d->indexes[ i ] ) );
            if ( p->optimal() ) {
                addPlan( p, checkFirst );
                return;
            } else if ( !p->unhelpful() ) {
                plans.push_back( p );
            }
        }
        for( PlanSet::iterator i = plans.begin(); i != plans.end(); ++i )
            addPlan( *i, checkFirst );

        // Table scan plan
        addPlan( PlanPtr( new QueryPlan( fbs_, order_ ) ), checkFirst );
    }
Пример #2
0
    void QueryPlanSet::addOtherPlans( bool checkFirst ) {
        const char *ns = _frsp->ns();
        NamespaceDetails *d = nsdetails( ns );
        if ( !d )
            return;

        // If table scan is optimal or natural order requested or tailable cursor requested
        if ( !_frsp->matchPossible() || ( _frsp->noNontrivialRanges() && _order.isEmpty() ) ||
                ( !_order.isEmpty() && !strcmp( _order.firstElement().fieldName(), "$natural" ) ) ) {
            // Table scan plan
            addPlan( QueryPlanPtr( new QueryPlan( d, -1, *_frsp, *_originalFrsp, _originalQuery, _order ) ), checkFirst );
            return;
        }

        bool normalQuery = _hint.isEmpty() && _min.isEmpty() && _max.isEmpty();

        PlanSet plans;
        QueryPlanPtr optimalPlan;
        for( int i = 0; i < d->nIndexes; ++i ) {
            if ( normalQuery ) {
                if ( !_frsp->matchPossibleForIndex( d, i, d->idx( i ).keyPattern() ) ) {
                    // If no match is possible, only generate a trival plan that won't
                    // scan any documents.
                    QueryPlanPtr p( new QueryPlan( d, i, *_frsp, *_originalFrsp, _originalQuery, _order ) );
                    addPlan( p, checkFirst );
                    return;
                }
                if ( !QueryUtilIndexed::indexUseful( *_frsp, d, i, _order ) ) {
                    continue;
                }
            }

            QueryPlanPtr p( new QueryPlan( d, i, *_frsp, *_originalFrsp, _originalQuery, _order ) );
            if ( p->optimal() ) {
                if ( !optimalPlan.get() ) {
                    optimalPlan = p;
                }
            }
            else if ( !p->unhelpful() ) {
                plans.push_back( p );
            }
        }
        if ( optimalPlan.get() ) {
            addPlan( optimalPlan, checkFirst );
            return;
        }
        for( PlanSet::iterator i = plans.begin(); i != plans.end(); ++i )
            addPlan( *i, checkFirst );

        // Table scan plan
        addPlan( QueryPlanPtr( new QueryPlan( d, -1, *_frsp, *_originalFrsp, _originalQuery, _order ) ), checkFirst );
    }