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,
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"
}
]
网友评论