美文网首页
Mongodb进阶

Mongodb进阶

作者: 1angxi | 来源:发表于2015-07-07 17:59 被阅读462次

    Mongodb的增删查改操作是很简单的。有必要再学点高深的东西,这篇文章就是做这个的。

    1、index

    建立索引的基本操作:

    >>> from pymongo import ASCENDING, DESCENDING
    >>> posts.create_index([("date", DESCENDING), ("author", ASCENDING)])
    u'date_-1_author_1'
    >>> posts.find({"date": {"$lt": d}}).sort("author").explain()["cursor"]
    u'BtreeCursor date_-1_author_1'
    >>> posts.find({"date": {"$lt": d}}).sort("author").explain()["nscanned"]
    2
    

    索引会通过建立B树的方式提高数据的查找速度。

    学会使用索引对于提高服务性能来说很有意义。

    索引是用来加快查询速度的,事物都有双面性的,同时在每次插入、更新和删除操作时都会产生额外的开销。索引有时并不能解决查询慢的问题,一般来说,返回集合中一半以上的结果,全表扫描要比查询索引更高效些。

    创建太多索引,会导致插入非常慢,同时还会占用很大空间。可以通过explain和hint工具来分析。索引有方向的,倒序还是升序。每个集合默认的最大索引个数为64个。

    查看索引的命令:

    db.ttlsa_events.getIndexes();
    
    [
            {
                    "v" : 1,
                    "key" : {
                            "_id" : 1
                    },
                    "ns" : "ttlsa_login.ttlsa_events",
                    "name" : "_id_"
            },
            {
                    "v" : 1,
                    "key" : {
                            "stmp" : -1
                    },
                    "ns" : "ttlsa_login.ttlsa_events",
                    "name" : "stmp_-1"
            },
            {
                    "v" : 1,
                    "key" : {
                            "uid" : 1,
                            "stmp" : -1
                    },
                    "ns" : "ttlsa_login.ttlsa_events",
                    "name" : "uid_1_stmp_-1"
            }
    ]
    

    此实例中有三个索引,其中id是创建表的时候自动创建的索引,不能删除。uid_1_stmp-1是组合索引。1表示升序,-1表示降序。

    创建索引:

    当有大量数据时,创建索引会非常耗时,可以指定到后台执行,只需指定“backgroud:true”即可。如:

    db.ttlsa_posts.ensureIndex({pid:1},{backgroud:true});
    

    组合索引:

    db.ttlsa_comments.ensureIndex({"properties.user":1,"properties.email":1})
    > db.ttlsa_comments.find({"properties.user":'ttlsa',"properties.email":'ttlsa@ttlsa.com'})
    > db.ttlsa_comments.find({"properties.user":'ttlsa'})
    > db.ttlsa_comments.find().sort({"properties.user":1})
    

    对多个值进行组合索引,查询时,子查询与索引前缀匹配时,才可以使用该组合索引。

    创建唯一索引:

    db.ttlsa_posts.ensureIndex({pid:1},{unique:true})
    
    > db.ttlsa_posts.ensureIndex({pid:1},{unique:true, dropDups:true})
    

    当为已有的集合创建索引,可能有些数据已经有重复了的,那么创建唯一索引将失败。可以使用dropDups来保留第一个文档,而后的重复文档将删除,这种方法慎重操作。

    删除索引:

    > db.collection.dropIndexes()
    

    删除某个索引:

    > db.collection.dropIndex({x:1})
    

    2、explain执行计划

    使用explain命令返回查询使用的索引情况,耗时,扫描文档数等等统计信息。

    > db.ttlsa_events.find({uid:178620830}).explain()
    {
            "cursor" : "BtreeCursor uid_1_stmp_-1",
            "isMultiKey" : false,
            "n" : 2,
            "nscannedObjects" : 2,
            "nscanned" : 2,
            "nscannedObjectsAllPlans" : 2,
            "nscannedAllPlans" : 2,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 0,
            "nChunkSkips" : 0,
            "millis" : 4,
            "indexBounds" : {
                    "uid" : [
                            [
                                    178620830,
                                    178620830
                            ]
                    ],
                    "stmp" : [
                            [
                                    {
                                            "$maxElement" : 1
                                    },
                                    {
                                            "$minElement" : 1
                                    }
                            ]
                    ]
            },
            "server" : "TTLSA-191155:27017"
    }
    

    字段说明:

    • cursor:返回游标类型
    • isMultiKey:是否使用组合索引
    • n:返回文档数量
    • nscannedObjects:被扫描的文档数量
    • nscanned:被检查的文档或索引条目数量
    • scanAndOrder:是否在内存中排序
    • indexOnly:
    • nYields:该查询为了等待写操作执行等待的读锁的次数
    • nChunkSkips:
    • millis:耗时(毫秒)
    • indexBounds:所使用的索引
    • server: 服务器主机.

    3、profiling

    查看profile级别:

    > db.getProfilingLevel()
    0
    

    设置profiling级别:

    > db.setProfilingLevel( level , slowms ) 
    > db.setProfilingLevel(2,10)
    { "was" : 0, "slowms" : 100, "ok" : 1 }
    

    profile的级别可以取0,1,2 表示的意义如下:

    • 0 – 不开启 默认级别
    • 1 – 记录慢命令 (默认为>100ms)
    • 2 – 记录所有命令

    查询profiling记录:
    MongoDB Profile 记录是直接存在系统 db 里的,记录位置system.profile 。

    > db.system.profile.find().sort({$natural:-1}).limit(1)
    { "ts" : ISODate("2013-07-18T09:56:59.546Z"), "op" : "query", "ns" : "ttlsa_event.ttlsa_events", "query" : { "$query" : { "uid" : 161484152, "stmp" : { "$gt" : 0 } }, "$orderby" : { "stmp" : -1 } }, "ntoreturn" : 0, "ntoskip" : 0, "nscanned" : 35, "keyUpdates" : 0, "numYield" : 0, "lockStats" : { "timeLockedMicros" : { "r" : NumberLong(354), "w" : NumberLong(0) }, "timeAcquiringMicros" : { "r" : NumberLong(3), "w" : NumberLong(3) } }, "nreturned" : 35, "responseLength" : 7227, "millis" : 0, "client" : "10.1.242.209", "user" : "" }
    > db.system.profile.find().pretty().limit(1)
    {
            "ts" : ISODate("2013-07-18T09:53:40.103Z"),
            "op" : "query",
            "ns" : "ttlsa_event.ttlsa_event_friends",
            "query" : {
                    "_id" : 195794232
            },
            "ntoreturn" : 1,
            "idhack" : true,
            "keyUpdates" : 0,
            "numYield" : 0,
            "lockStats" : {
                    "timeLockedMicros" : {
                            "r" : NumberLong(45),
                            "w" : NumberLong(0)
                    },
                    "timeAcquiringMicros" : {
                            "r" : NumberLong(3),
                            "w" : NumberLong(5)
                    }
            },
            "responseLength" : 20,
            "millis" : 0,
            "client" : "10.1.22.199",
            "user" : ""
    }
    

    字段说明:
    ts: 该命令在何时执行
    op: 操作类型
    query: 本命令的详细信息
    responseLength: 返回结果集的大小
    ntoreturn: 本次查询实际返回的结果集
    millis: 该命令执行耗时,以毫秒记

    > db.setProfilingLevel(0)
    { "was" : 2, "slowms" : 10, "ok" : 1 }
    > 
    > db.getProfilingLevel()
    0
    > db.system.profile.drop()
    true
    

    4、capped Collections

    capped Collections 比普通Collections 的读写效率高。Capped Collections 是高效率的Collection类型,它有如下特点:

    a. 固定大小;Capped Collections 必须事先创建,并设置大小:> db.createCollection("collection", {capped:true, size:100000})

    b. Capped Collections 可以insert 和update 操作,不能delete 操作。只能用drop()方法删除整个Collection。

    c. 默认基于Insert 的次序排序的。如果查询时没有排序,则总是按照insert 的顺序返回。

    d. FIFO。如果超过了Collection 的限定大小,则用FIFO 算法,新记录将替代最先insert的记录

    > db.createCollection("system.profile",{capped:true, size: 1000000})
    { "ok" : 1 }
    > db.system.profile.stats()
    {
            "ns" : "ttlsa_event.system.profile",
            "count" : 0,
            "size" : 0,
            "storageSize" : 1003520,
            "numExtents" : 1,
            "nindexes" : 0,
            "lastExtentSize" : 1003520,
            "paddingFactor" : 1,
            "systemFlags" : 0,
            "userFlags" : 0,
            "totalIndexSize" : 0,
            "indexSizes" : {
     
            },
            "capped" : true,
            "max" : 2147483647,
            "ok" : 1
    }
    

    相关文章

      网友评论

          本文标题:Mongodb进阶

          本文链接:https://www.haomeiwen.com/subject/hcwyqttx.html