注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

曾国藩的博客

 
 
 

日志

 
 

用MongoDB profiler分析慢查询 我用  

2014-05-07 18:45:55|  分类: SQL/Oracle/Mysql |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

http://blog.csdn.net/csfreebird/article/details/17259475

MongoDB profiler是一个很好的工具,可以帮助在数据库运行的时候分析慢查询。默认情况下,慢查询指的是查询时间在100ms以上。这个值是可以修改的。

先看一下怎么用。

step 1 登录到primary server

假定有一个MongoDB Replica-set集群,用mongo shell登录到primary server上。

并且进入你要监控的数据库

use kaimei


step 2 设置profile level

  1. db.setProfilingLevel(1)  
db.setProfilingLevel(1)


step 3 查看慢查询语句

现在MongoDB server会运行的较慢,会将发现的慢查询语句写到db.system.profile集合中。下面演示了查找最近一条慢查询的方法

  1. rs1:PRIMARY> db.system.profile.find().limit(1).sort( { ts : -1 } ).pretty()  
  2. {  
  3.     "op" : "query",  
  4.     "ns" : "kaimei.digital_message",  
  5.     "query" : {  
  6.         "query" : {  
  7.             "display_id" : {  
  8.                 "$in" : [  
  9.                     ObjectId("52312efca9bb51d66fa724a8"),  
  10.                     ObjectId("52312efca9bb51d66fa724ab"),  
  11.                     ObjectId("52312efca9bb51d66fa724ac"),  
  12.                     ObjectId("52312efca9bb51d66fa724ae"),  
  13.                     ObjectId("5252c23133f6792263dd1cfe"),  
  14.                     ObjectId("5271ab5033f6792263dd8cfc"),  
  15.                     ......  
  16.                     ObjectId("527710eb33f6792263ddba43"),  
  17.                     ObjectId("527710eb33f6792263ddba44")  
  18.                 ]  
  19.             },  
  20.             "status" : {  
  21.                 "$nin" : [  
  22.                     "success",  
  23.                     "deprecated"  
  24.                 ]  
  25.             }  
  26.         },  
  27.         "orderby" : {  
  28.             "_id" : 1  
  29.         }  
  30.     },  
  31.     "ntoreturn" : 0,  
  32.     "ntoskip" : 0,  
  33.     "nscanned" : 210342,  
  34.     "keyUpdates" : 0,  
  35.     "numYield" : 454,  
  36.     "lockStats" : {  
  37.         "timeLockedMicros" : {  
  38.             "r" : NumberLong(1755835),  
  39.             "w" : NumberLong(0)  
  40.         },  
  41.         "timeAcquiringMicros" : {  
  42.             "r" : NumberLong(1145626),  
  43.             "w" : NumberLong(1599)  
  44.         }  
  45.     },  
  46.     "nreturned" : 0,  
  47.     "responseLength" : 20,  
  48.     "millis" : 1147,  
  49.     "ts" : ISODate("2013-12-10T13:08:05.839Z"),  
  50.     "client" : "192.168.1.58",  
  51.     "allUsers" : [ ],  
  52.     "user" : ""  
  53. }  
rs1:PRIMARY> db.system.profile.find().limit(1).sort( { ts : -1 } ).pretty()
{
    "op" : "query",
    "ns" : "kaimei.digital_message",
    "query" : {
        "query" : {
            "display_id" : {
                "$in" : [
                    ObjectId("52312efca9bb51d66fa724a8"),
                    ObjectId("52312efca9bb51d66fa724ab"),
                    ObjectId("52312efca9bb51d66fa724ac"),
                    ObjectId("52312efca9bb51d66fa724ae"),
                    ObjectId("5252c23133f6792263dd1cfe"),
                    ObjectId("5271ab5033f6792263dd8cfc"),
                    ......
                    ObjectId("527710eb33f6792263ddba43"),
                    ObjectId("527710eb33f6792263ddba44")
                ]
            },
            "status" : {
                "$nin" : [
                    "success",
                    "deprecated"
                ]
            }
        },
        "orderby" : {
            "_id" : 1
        }
    },
    "ntoreturn" : 0,
    "ntoskip" : 0,
    "nscanned" : 210342,
    "keyUpdates" : 0,
    "numYield" : 454,
    "lockStats" : {
        "timeLockedMicros" : {
            "r" : NumberLong(1755835),
            "w" : NumberLong(0)
        },
        "timeAcquiringMicros" : {
            "r" : NumberLong(1145626),
            "w" : NumberLong(1599)
        }
    },
    "nreturned" : 0,
    "responseLength" : 20,
    "millis" : 1147,
    "ts" : ISODate("2013-12-10T13:08:05.839Z"),
    "client" : "192.168.1.58",
    "allUsers" : [ ],
    "user" : ""
}


这条语句用了1147 ms,查询涉及到_id, display_id和status三个字段. 的确够慢。


step 4 建立索引优化查询

现在看看有什么方法能够优化,通过getIndexes发现display_id和status没有建立索引。因此创建索引

  1. rs1:PRIMARY> db.digital_message.ensureIndex({display_id: 1, status: 1}, {background: true} )  
  2. rs1:PRIMARY> db.digital_message.getIndexes()  
  3. [  
  4.         {  
  5.                 "v" : 1,  
  6.                 "key" : {  
  7.                         "_id" : 1  
  8.                 },  
  9.                 "ns" : "kaimei.digital_message",  
  10.                 "name" : "_id_"  
  11.         },  
  12.         {  
  13.                 "v" : 1,  
  14.                 "key" : {  
  15.                         "display_id" : 1,  
  16.                         "status" : 1  
  17.                 },  
  18.                 "ns" : "kaimei.digital_message",  
  19.                 "name" : "display_id_1_status_1",  
  20.                 "background" : true  
  21.         }  
  22. ]  
rs1:PRIMARY> db.digital_message.ensureIndex({display_id: 1, status: 1}, {background: true} )
rs1:PRIMARY> db.digital_message.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "ns" : "kaimei.digital_message",
                "name" : "_id_"
        },
        {
                "v" : 1,
                "key" : {
                        "display_id" : 1,
                        "status" : 1
                },
                "ns" : "kaimei.digital_message",
                "name" : "display_id_1_status_1",
                "background" : true
        }
]

background: true很重要,可以保证建立索引过程中数据库仍然可以处理请求。这里我建立的是双字段的组合索引。


现在再试一下:

  1.                 ]  
  2.         },  
  3.         "status" : {  
  4.                 "$nin" : [  
  5.                         "success",  
  6.                         "deprecated"  
  7.                 ]  
  8.         }  
  9. },  
  10. "updateobj" : {  
  11.         "$set" : {  
  12.                 "status" : "sending"  
  13.         }  
  14. },  
  15. "nscanned" : 37693,  
  16. "nupdated" : 0,  
  17. "keyUpdates" : 0,  
  18. "numYield" : 3,  
  19. "lockStats" : {  
  20.         "timeLockedMicros" : {  
  21.                 "r" : NumberLong(0),  
  22.                 "w" : NumberLong(248113)  
  23.         },  
  24.         "timeAcquiringMicros" : {  
  25.                 "r" : NumberLong(0),  
  26.                 "w" : NumberLong(114619)  
  27.         }  
  28. },  
  29. "millis" : 149,  
  30. "ts" : ISODate("2013-12-10T13:30:46.400Z"),  
  31. "client" : "192.168.1.55",  
  32. "allUsers" : [ ],  
  33. "user" : ""  
                        ]
                },
                "status" : {
                        "$nin" : [
                                "success",
                                "deprecated"
                        ]
                }
        },
        "updateobj" : {
                "$set" : {
                        "status" : "sending"
                }
        },
        "nscanned" : 37693,
        "nupdated" : 0,
        "keyUpdates" : 0,
        "numYield" : 3,
        "lockStats" : {
                "timeLockedMicros" : {
                        "r" : NumberLong(0),
                        "w" : NumberLong(248113)
                },
                "timeAcquiringMicros" : {
                        "r" : NumberLong(0),
                        "w" : NumberLong(114619)
                }
        },
        "millis" : 149,
        "ts" : ISODate("2013-12-10T13:30:46.400Z"),
        "client" : "192.168.1.55",
        "allUsers" : [ ],
        "user" : ""
}

可以看到速度提升了很多。由于我的in查询至少涉及到1500行以上记录的记录,所以这个149 ms的查询时间是可以接受的。

以后再打开profile时,可以修改慢查询的衡量标准,比如下面就改成了200 ms以上的才算慢查询。

  1. db.setProfilingLevel(1, 200)  
db.setProfilingLevel(1, 200)


 

step 5 清空profile集合,还原到最初。

  1. db.setProfilingLevel(0)  
  2. db.system.profile.drop()  
  3. db.createCollection( "system.profile", { capped: true, size:4000000 } )  
db.setProfilingLevel(0)
db.system.profile.drop()
db.createCollection( "system.profile", { capped: true, size:4000000 } )


官方文档参考:http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

  评论这张
 
阅读(896)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018