1.explain()方法

概念

通常来说,我们都需要对查询语句进行分析,来查看语句是否使用了索引还是全表扫描等。mysql中提供了EXLPAIN()关键字,而mongo中同样提供了explain()方法进行查询分析

语句

db.${collectionName}.find().explain(${分析方式})
其中分析方式参数可以缺省,具体参数介绍如下:

  1. queryPlanner:默认参数,缺省时默认为queryPlanner
  2. executionStats:会返回最佳执行计划的一些统计信息
  3. allPlansExecution:用来获取所有执行计划

    2.explain()关键字段讲解

    queryPlanner

    使用: db.test.find({t:1}).explain()语句进行查询分析
    返回字段具体如下:

    1. {
    2. "queryPlanner":{
    3. "plannerVersion":1,
    4. "namespace":"db_test.test",
    5. "indexFilterSet":false,
    6. "parsedQuery":{
    7. "t":{
    8. "$eq":1
    9. }
    10. },
    11. "queryHash":"E6282CBD",
    12. "planCacheKey":"BD8C7DD3",
    13. "winningPlan":{
    14. "stage":"FETCH",
    15. "inputStage":{
    16. "stage":"IXSCAN",
    17. "keyPattern":{
    18. "t":1
    19. },
    20. "indexName":"t_1",
    21. "isMultiKey":false,
    22. "multiKeyPaths":{
    23. "t":[
    24. ]
    25. },
    26. "isUnique":false,
    27. "isSparse":false,
    28. "isPartial":false,
    29. "indexVersion":2,
    30. "direction":"forward",
    31. "indexBounds":{
    32. "t":[
    33. "[1.0, 1.0]"
    34. ]
    35. }
    36. }
    37. },
    38. "rejectedPlans":[
    39. ]
    40. },
    41. "serverInfo":{
    42. "host":"instance-opiu1svq",
    43. "port":27017,
    44. "version":"4.4.15",
    45. "gitVersion":"bc17cf2c788c5dda2801a090ea79da5ff7d5fac9"
    46. },
    47. "ok":1
    48. }

    winningPlan 属性是一个递归结构:winningPlan 指向获胜查询计划中的最后一个阶段,每个阶段都有一个描述前一阶段的 inputStage 属性。
    在上述计划中,有两个阶段:IXSCAN 和 FETCH(从递归最底层往外看)。这意味着第一个 MongoDB 使用 { t: 1 } 索引来确定哪些文档与查询匹配,然后获取各个文档
    重点关注stage字段

  4. 如果stage字段为”IXSCAN”,代表使用了索引。

  5. 如果stage字段为”COLLSCAN”,代表扫描了整个集合进行文档查询

    executionStats

    使用: db.test.find({t:1}).explain(“executionStats”)语句进行查询分析
    返回字段具体如下:

    1. {
    2. "queryPlanner" : {
    3. "plannerVersion" : 1,
    4. "namespace" : "db_test.test",
    5. "indexFilterSet" : false,
    6. "parsedQuery" : {
    7. "t" : {
    8. "$eq" : 1
    9. }
    10. },
    11. "winningPlan" : {
    12. "stage" : "FETCH",
    13. "inputStage" : {
    14. "stage" : "IXSCAN",
    15. "keyPattern" : {
    16. "t" : 1
    17. },
    18. "indexName" : "t_1",
    19. "isMultiKey" : false,
    20. "multiKeyPaths" : {
    21. "t" : [ ]
    22. },
    23. "isUnique" : false,
    24. "isSparse" : false,
    25. "isPartial" : false,
    26. "indexVersion" : 2,
    27. "direction" : "forward",
    28. "indexBounds" : {
    29. "t" : [
    30. "[1.0, 1.0]"
    31. ]
    32. }
    33. }
    34. },
    35. "rejectedPlans" : [ ]
    36. },
    37. "executionStats" : {
    38. "executionSuccess" : true,
    39. "nReturned" : 1,
    40. "executionTimeMillis" : 0,
    41. "totalKeysExamined" : 1,
    42. "totalDocsExamined" : 1,
    43. "executionStages" : {
    44. "stage" : "FETCH",
    45. "nReturned" : 1,
    46. "executionTimeMillisEstimate" : 0,
    47. "works" : 2,
    48. "advanced" : 1,
    49. "needTime" : 0,
    50. "needYield" : 0,
    51. "saveState" : 0,
    52. "restoreState" : 0,
    53. "isEOF" : 1,
    54. "docsExamined" : 1,
    55. "alreadyHasObj" : 0,
    56. "inputStage" : {
    57. "stage" : "IXSCAN",
    58. "nReturned" : 1,
    59. "executionTimeMillisEstimate" : 0,
    60. "works" : 2,
    61. "advanced" : 1,
    62. "needTime" : 0,
    63. "needYield" : 0,
    64. "saveState" : 0,
    65. "restoreState" : 0,
    66. "isEOF" : 1,
    67. "keyPattern" : {
    68. "t" : 1
    69. },
    70. "indexName" : "t_1",
    71. "isMultiKey" : false,
    72. "multiKeyPaths" : {
    73. "t" : [ ]
    74. },total
    75. "isUnique" : false,
    76. "isSparse" : false,
    77. "isPartial" : false,
    78. "indexVersion" : 2,
    79. "direction" : "forward",
    80. "indexBounds" : {
    81. "t" : [
    82. "[1.0, 1.0]"
    83. ]
    84. },
    85. "keysExamined" : 1,
    86. "seeks" : 1,
    87. "dupsTested" : 0,
    88. "dupsDropped" : 0
    89. }
    90. }
    91. },
    92. "serverInfo" : {
    93. "host" : "instance-opiu1svq",
    94. "port" : 27017,
    95. "version" : "4.4.15",
    96. "gitVersion" : "bc17cf2c788c5dda2801a090ea79da5ff7d5fac9"
    97. },
    98. "ok" : 1
    99. }

    如图,多了一个executionStats属性。重点关注executionTimeMillis字段以及totalDocsExamined字段

  6. executionTimeMillis:mongo服务器执行查询花费的时间,但是并不包括接受命令以及返回命令的网络耗时。因此该字段时间短,不代表整体查询时间短

  7. totalDocsExamined:mongo服务器查询结果必须检索的文档数量。如果触发了覆盖索引查询,那么这个字段=0

    allPlansExecution

    allPlansExecution返回的字段与executionStats一致,这里不做过多描述

    3.hint()方法

    概念

    $hint 运算符(也叫“强制查询优化器”)能够使用指定的索引来进行查询,以此来测试查询的性能。
    如果想要测试具有不同索引的查询性能时,此功能特别有用。
    在 mongo shell 中可以使用 $hint 的辅助方法 hint() 来使用此功能

    语句

  8. 使用hint强制指定索引查询:db.${collectionName}.hint({{$indexName:1/-1},…})

  9. 使用hint强制指定索引查询进行分析:db.${collectionName}.hint({{$indexName:1/-1},…}).explain()