diff options
author | David Storch <david.storch@10gen.com> | 2015-02-18 18:26:42 -0500 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2015-02-19 13:44:17 -0500 |
commit | ae341c89d09b634047dd080af0f9e173e6d8b6e5 (patch) | |
tree | 00f39c811f6e391754aafe22f021756267057806 /src | |
parent | 44a8c494fcb1259a00328ebf5cf29c1b7de2a075 (diff) | |
download | mongo-ae341c89d09b634047dd080af0f9e173e6d8b6e5.tar.gz |
SERVER-14071 do not cache plans which return zero results
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/exec/multi_plan.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/mongo/db/exec/multi_plan.cpp b/src/mongo/db/exec/multi_plan.cpp index 6f8b84260e7..fb427c9fb46 100644 --- a/src/mongo/db/exec/multi_plan.cpp +++ b/src/mongo/db/exec/multi_plan.cpp @@ -294,12 +294,30 @@ namespace mongo { } } + // If the winning plan produced no results during the ranking period (and, therefore, no + // plan produced results during the ranking period), then we will not create a plan cache + // entry. + if (alreadyProduced.empty() && NULL != _collection) { + size_t winnerIdx = ranking->candidateOrder[0]; + LOG(1) << "Winning plan had zero results. Not caching." + << " ns: " << _collection->ns() + << " " << _query->toStringShort() + << " winner score: " << ranking->scores[0] + << " winner summary: " + << Explain::getPlanSummary(_candidates[winnerIdx].root); + } + // Store the choice we just made in the cache. In order to do so, - // 1) the query must be of a type that is safe to cache, and - // 2) two or more plans cannot have tied for the win. Caching in the - // case of ties can cause successive queries of the same shape to - // use a bad index. - if (PlanCache::shouldCacheQuery(*_query) && !ranking->tieForBest) { + // 1) the query must be of a type that is safe to cache, + // 2) two or more plans cannot have tied for the win. Caching in the case of ties can + // cause successive queries of the same shape to use a bad index. + // 3) Furthermore, the winning plan must have returned at least one result. Plans which + // return zero results cannot be reliably ranked. Such query shapes are generally + // existence type queries, and a winning plan should get cached once the query finds a + // result. + if (PlanCache::shouldCacheQuery(*_query) + && !ranking->tieForBest + && !alreadyProduced.empty()) { // Create list of candidate solutions for the cache with // the best solution at the front. std::vector<QuerySolution*> solutions; |