summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2015-02-18 18:26:42 -0500
committerDavid Storch <david.storch@10gen.com>2015-02-19 13:44:17 -0500
commitae341c89d09b634047dd080af0f9e173e6d8b6e5 (patch)
tree00f39c811f6e391754aafe22f021756267057806 /src
parent44a8c494fcb1259a00328ebf5cf29c1b7de2a075 (diff)
downloadmongo-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.cpp28
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;