Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-15924

planCacheListPlans command can report incorrect averageScore and stdDevScore in "feedback" section

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor - P4
    • Resolution: Gone away
    • Affects Version/s: 2.6.5, 2.7.8
    • Fix Version/s: None
    • Component/s: Querying
    • Labels:
      None
    • Operating System:
      ALL
    • Steps To Reproduce:
      Hide

      > t.drop();
      > for (var i = 0; i < 20; i++) { t.insert({_id: i, a: i, b: 1}); }
      > t.ensureIndex({a: 1});
      > t.ensureIndex({b: 1});
       
      // Run a query twice. The first run causes a plan to be cached. The second
      // adds a feedback entry.
      > t.find({a: {$lt: 3}, b: 1}).next()
      > t.find({a: {$lt: 3}, b: 1}).next()
       
      // Get the plan cache entry.
      > t.getPlanCache().getPlansByQuery({a: {$lt: 3}, b: 1})
      [
         ...
      		"feedback" : {
      			"nfeedback" : 1,
      			"averageScore" : 0, // XXX: incorrect!
      			"stdDevScore" : 0, // XXX: incorrect!
      			"scores" : [
      				{
      					"score" : 1.7503
      				}
      			]
      		},
      		"filterSet" : false
      	},
         ...
      ]
       
      // After running the query a few more times, the average and std dev are computed.
      > for (var i = 0; i < 20; i++) { t.find({a: {$lt: 3}, b: 1}).next(); }
      > t.getPlanCache().getPlansByQuery({a: {$lt: 3}, b: 1})
      [
         ...
      		"feedback" : {
      			"nfeedback" : 20,
      			"averageScore" : 1.7502999999999997,
      			"stdDevScore" : 2.278129578503827e-16,
      			"scores" : [
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				},
      				{
      					"score" : 1.7503
      				}
      			]
      		},
         ...
      ]

      Show
      > t.drop(); > for (var i = 0; i < 20; i++) { t.insert({_id: i, a: i, b: 1}); } > t.ensureIndex({a: 1}); > t.ensureIndex({b: 1});   // Run a query twice. The first run causes a plan to be cached. The second // adds a feedback entry. > t.find({a: {$lt: 3}, b: 1}).next() > t.find({a: {$lt: 3}, b: 1}).next()   // Get the plan cache entry. > t.getPlanCache().getPlansByQuery({a: {$lt: 3}, b: 1}) [ ... "feedback" : { "nfeedback" : 1, "averageScore" : 0, // XXX: incorrect! "stdDevScore" : 0, // XXX: incorrect! "scores" : [ { "score" : 1.7503 } ] }, "filterSet" : false }, ... ]   // After running the query a few more times, the average and std dev are computed. > for (var i = 0; i < 20; i++) { t.find({a: {$lt: 3}, b: 1}).next(); } > t.getPlanCache().getPlansByQuery({a: {$lt: 3}, b: 1}) [ ... "feedback" : { "nfeedback" : 20, "averageScore" : 1.7502999999999997, "stdDevScore" : 2.278129578503827e-16, "scores" : [ { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 }, { "score" : 1.7503 } ] }, ... ]

      Description

      The planCacheListPlans command, also exposed via the getPlansByQuery shell helper displays the plan that has been cached for a particular query shape. Each time that a cached plan is reused for another instance of the query shape, stats about the performance of the query are tracked. These stats are used to update the "feedback" section of the planCacheListPlans output. This section shows how many times the cached plan was used, as well as the scores for each use of the plan.

      The "averageScore" and "stdDevScore" fields are statistics taken over the history of scores for each run of the cached plan. These statistics are first computed once the plan has been used some small number of times, n. (Currently n defaults to 20.) The list plans command, however, reports the average and standard deviation as 0 even before these values have been computed. See "Steps to Reproduce" for details.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                david.storch David Storch
                Reporter:
                david.storch David Storch
                Participants:
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: