建立索引是数据库最消耗资源的操作之一,应采用对生产服务器影响最小的方式建立索引;
1、在独立的服务器上建立索引,可在空闲时间于后台建立索引:
> db.foo.ensureIndex({"x":1}, {"background":true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
大坑在此:在前台建立索引期间会锁定数据库,导致无法进行读写操作;而在后台建立索引期间会定期释放写锁,从而保证其他操作的正常运行;
2、在副本集上建立索引
最简单方式,对于小集合在主节点建立索引,等待被复制到其他备份节点;
较大集合推荐方式:
对于备份节点:关闭一个备份节点、将其作为独立的节点启动、建立索引、重新将其作为成员加入副本集、对每个备份节点执行以上操作;
对于主节点:(以下2种根据实际情况选择)
1)于后台在主节点中建立索引,会对主节点的性能造成压力;
2)关闭主节点,像备份节点建立索引的方式建立索引,需要停运数据库;
3、在分片集群上建立索引
与在副本集中建立索引的步骤相同,需要在每个分片上分别建立一次;
4、删除索引,根据索引名删除
> db.foo.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "mydb.foo"
},
{
"v" : 2,
"key" : {
"x" : 1
},
"name" : "x_1",
"ns" : "mydb.foo",
"background" : true
}
]
> db.foo.dropIndex("x_1")
{ "nIndexesWas" : 2, "ok" : 1 }
删除所有索引,但无法删除_id索引,只有删除整个集合才能删除_id索引;
> db.foo.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "mydb.foo"
}
]
> db.foo.dropIndexes()
{
"nIndexesWas" : 1,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.foo.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "mydb.foo"
}
]
5、注意OOM
Linux的内存溢出杀手 out-of-memory killer负责终止使用过多内存的进程;
如在建立索引时mongod突然消失,检查/var/log/messages文件中关于OOM Killer的输出信息;
在后台建立索引或增加交换空间可以避免此类情况;