美文网首页程序员
MongoDB:创建索引需要注意的事项

MongoDB:创建索引需要注意的事项

作者: dex0423 | 来源:发表于2020-10-14 16:00 被阅读0次

    1. 尽可能在写入数据前把索引创建好

    • MongoDB 创建索引比较耗时,如果在数据写入完毕以后再去创建索引,创建的过程会异常的漫长;
    • 所以,尽可能在设计表的时候就明确需要那些索引,创建集合的同时创建索引,之后再写入数据;

    2. 前台创建索引会严重影响 MongoDB

    • 如果集合里面有很多数据,并且你使用的是前台索引,那么此时创建索引会把这个集合锁起来,所有对这个集合的写入操作都会挂起,查询操作也会异常的缓慢;
    • 此时,如果集合中数据已经有很多,创建索引的过程可能需要好几个小时,挂起的写入数据会堆积在内存里面,很有可能把内存撑爆;

    3. 尽可能的在后台创建索引

    • 后台创建索引不会影响 MongoDB 的使用,但是耗费的时间会更久;
    db.collectionName.create_index({'索引字段':1}, {'name': '索引的名字'}, {background:true})
    

    4. 后台创建索引也会影响 MongoDB 的性能

    • 在后台创建索引期间,MongoDB 执行效能会下降,应在合理的时间段内完成索引的创建,不影响正常的业务。

    5. 查看索引创建的进度的方法

    db.currentOp(
        {
            $or: [
                    { op: "command", "query.createIndexes": { $exists: true } },
                    { op: "insert", ns: /\.system\.indexes\b/ }
                ]
        }
    )
    
    • 返回内容如下所示:
    {
            "inprog" : [
                    {
                            "desc" : "conn2163",
                            "threadId" : "4136",
                            "connectionId" : 2163,
                            "client" : "183.14.135.173:51330",
                            "active" : true,
                            "opid" : 1153352,
                            "secs_running" : 5075,
                            "microsecs_running" : NumberLong("5075063463"),
                            "op" : "command",
                            "ns" : "EPO.$cmd",
                            "query" : {
                                    "createIndexes" : "EPO_patent",
                                    "indexes" : [
                                            {
                                                    "key" : {
                                                            "patent_num" : 1
                                                    },
                                                    "name" : "patent_num_1"
                                            }
                                    ]
                            },
                            "msg" : "Index Build Index Build: 2651232/6334763 41%",     // 【注意】这里的 41% 就是创建索引的进度
                            "progress" : {
                                    "done" : 2651232,
                                    "total" : 6334763
                            },
                            "numYields" : 0,
                            "locks" : {
                                    "Global" : "w",
                                    "Database" : "W",
                                    "Collection" : "w"
                            },
                            "waitingForLock" : false,
                            "lockStats" : {
                                    "Global" : {
                                            "acquireCount" : {
                                                    "r" : NumberLong(1),
                                                    "w" : NumberLong(1)
                                            }
                                    },
                                    "Database" : {
                                            "acquireCount" : {
                                                    "W" : NumberLong(1)
                                            },
                                            "acquireWaitCount" : {
                                                    "W" : NumberLong(1)
                                            },
                                            "timeAcquiringMicros" : {
                                                    "W" : NumberLong(19885)
                                            }
                                    },
                                    "Collection" : {
                                            "acquireCount" : {
                                                    "w" : NumberLong(1)
                                            }
                                    }
                            }
                    }
            ],
            "ok" : 1
    }
    
    • 索引的进度在此处显示,这里的 41% 就是创建索引的进度:
    "msg" : "Index Build Index Build: 2651232/6334763 41%",
    
    • 如果返回如下内容,则表示索引创建成功
    mongo { "inprog" : [ ], "ok" : 1 }
    

    6. 要用正确方法中断创建索引进程

    • ctrl + c 中断的是与 MongoDB 的连接,并不能中断创建索引的进程;
    • 重启 MongoDB 也不能中断创建索引的进程;
    • 正确的方法是,先查看创建索引进程的 pid 进程号,方法和上面查看进度的方法一样:
    db.currentOp(
        {
            $or: [
                    { op: "command", "query.createIndexes": { $exists: true } },
                    { op: "insert", ns: /\.system\.indexes\b/ }
                ]
        }
    )
    
    • 然后,从返回的内容中找到类似于下面的内容,这串数字就是 pid 进程号;
    "opid" : 1153352,
    
    • 最后,杀死 pid 进程
    db.killOp(pid 进程号)
    
    • 补充:
      -- 有些文章说可以使用 db.currentOp() 命令然后从返回值中查找 json "lockType": "write",在其附近可以找到 pid 字段的键值对,这种方法我尝试以后并没有找到!

    7. 创建索引时最好指定 索引 name

    • 如果不指定索引的 name,则mongo会在索引 key 后面加 _1 后缀,
    db.EPO_pdf.ensureIndex({'page_id':1}, {"name":"page_id"}, {background:true})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    > db.EPO_pdf.getIndexes()
    [
            {
                    "v" : 2,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "EPO.EPO_pdf"
            },
            {
                    "v" : 2,
                    "key" : {
                            "page_id" : 1
                    },
                    "name" : "page_id",
                    "ns" : "EPO.EPO_pdf"
            }
    ]
    

    相关文章

      网友评论

        本文标题:MongoDB:创建索引需要注意的事项

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