diff --git a/src/mongo/db/query/explain.cpp b/src/mongo/db/query/explain.cpp index c27f425b28eba..0c4ccbc7cfaa0 100644 --- a/src/mongo/db/query/explain.cpp +++ b/src/mongo/db/query/explain.cpp @@ -376,6 +376,8 @@ void Explain::planCacheEntryToBSON(const PlanCacheEntry& entry, BSONObjBuilder* // Append whether or not the entry is active. out->append("isActive", entry.isActive); out->append("works", static_cast(entry.works)); + // we can use this counter to get the highest frequency query sql in tht plancache + out->append("queryCount", static_cast(entry.queryCounters)); out->append("timeOfCreation", entry.timeOfCreation); if (entry.debugInfo) { diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index db367815f203e..3d4b32bdffb6e 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -647,6 +647,9 @@ class PrepareExecutionHelper { "query"_attr = redact(_cq->toStringShort())); } + PlanCache* cache = CollectionQueryInfo::get(_collection).getPlanCache(); + cache->increaseCacheQueryCounters(*_cq); + return buildCachedPlan( std::move(querySolution), plannerParams, cs->decisionWorks); } diff --git a/src/mongo/db/query/plan_cache.cpp b/src/mongo/db/query/plan_cache.cpp index c4e7fc7d37fc5..6e7fe5de40212 100644 --- a/src/mongo/db/query/plan_cache.cpp +++ b/src/mongo/db/query/plan_cache.cpp @@ -257,6 +257,7 @@ PlanCacheEntry::PlanCacheEntry(std::unique_ptr plannerD planCacheKey(planCacheKey), isActive(isActive), works(works), + queryCounters(0), debugInfo(std::move(debugInfo)), estimatedEntrySizeBytes(_estimateObjectSizeInBytes()) { invariant(this->plannerData); @@ -669,6 +670,20 @@ void PlanCache::deactivate(const CanonicalQuery& query) { entry->isActive = false; } +//increase the query counters which hit the plan +void PlanCache::increaseCacheQueryCounters(const CanonicalQuery& query) { + PlanCacheKey key = computeKey(query); + stdx::lock_guard cacheLock(_cacheMutex); + PlanCacheEntry* entry = nullptr; + Status cacheStatus = _cache.get(key, &entry); + if (!cacheStatus.isOK()) { + invariant(cacheStatus == ErrorCodes::NoSuchKey); + return; + } + invariant(entry); + entry->queryCounters++; +} + PlanCache::GetResult PlanCache::get(const CanonicalQuery& query) const { PlanCacheKey key = computeKey(query); return get(key); diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h index 161a5ed9697fc..af72d02cf4ad2 100644 --- a/src/mongo/db/query/plan_cache.h +++ b/src/mongo/db/query/plan_cache.h @@ -401,6 +401,9 @@ class PlanCacheEntry { // cause this value to be increased. size_t works = 0; + //the query count that use this plan to run the sql + uint64_t queryCounters = 0; + // Optional debug info containing detailed statistics. Includes a description of the query which // resulted in this plan cache's creation as well as runtime stats from the multi-planner trial // period that resulted in this cache entry. @@ -519,6 +522,12 @@ class PlanCache { */ void deactivate(const CanonicalQuery& query); + /** + * increase the query counters that hit this cached plan. + * through this counters, we can get the hot query + */ + void increaseCacheQueryCounters(const CanonicalQuery& query); + /** * Look up the cached data access for the provided 'query'. Used by the query planner * to shortcut planning.