MongoDB索引管理
来源:互联网 发布:python 字符串相等 编辑:程序博客网 时间:2024/06/06 01:14
虽然MongoDB的索引在存储结构上都是一样的,但是根据不同的应用层需求,还是分成了唯一索引(unique)、稀疏索引(sparse)、多值索引(multikey)等几种类型。
唯一索引
唯一索引在创建时加上 unique:true 的选项即可,创建命令如下:
db.users.ensureIndex({username:
1
}, {unique:
true
})
上面的唯一索引创建后,如果insert一条username已经存在的数据,则会报如下的错误:
E11000 duplicate key error index: gardening.users.$username_1 dup key: { :
"kbanker"
}
如果你在一个已有数据的collection上创建唯一索引,若唯一索引对应的字段原来就有重复的数据项,那么创建会失败,我们需要加上一个dropDups的选项来强制将重复的项删除掉,命令如下例:
db.users.ensureIndex({username:
1
}, {unique:
true
, dropDups:
true
})
松散索引
如果你的数据中一些行中没有某个字段或字段值为null,那么如果在这个字段上建立普通索引,那么无此字段或值null的行也会参与到索引结构中,占用相应的空间。如果我们不希望这些值为空的行参与到我们的索引中,这时候可以采用松散索引,松散索引只会让指定字段不为空的行参与到索引创建中来。创建一个松散索引可以用下面的命令:
db.reviews.ensureIndex({user_id:
1
}, {sparse:
true
})
多值索引
MongoDB可以对一个array类型创建索引,比如像下面的结构,MongoDB可以在tags字段上创建索引:
{ name:
"Wheelbarrow"
,
tags: [
"tools"
,
"gardening"
,
"soil"
]
}
在生成索引时,会为tags中的三个值分别生成三个索引元素,索引中tools,gardening,soil三个值都会指向这同一行数据。相当于分裂成了三个独立的索引项。
索引管理
索引的创建和删除
创建和删除索引的方法有很多种,下面两个是比较原始的方法,通过对system.indexes这个collection进行相应的写操作来完成索引的创建:
spec = {ns:
"green.users"
, key: {‘addresses.zip’:
1
}, name: ‘zip’}
db.system.indexes.insert(spec,
true
)
上面命令往system.indexes中写入一条记录来创建索引,这条记录包含了要在上面创建索引的collection的名字空间,索引的信息,以及索引的名称。
创建完成后,我们可以通过下面命令找到我们创建的索引:
db.system.indexes.find()
{
"_id"
: ObjectId(
"4d2205c4051f853d46447e95"
),
"ns"
:
"green.users"
,
"key"
: {
"addresses.zip"
:
1
},
"name"
:
"zip"
,
"v"
:
0
}
要删除一个已创建的索引,我们可以使用下面的命令来实现:
use green
db.runCommand({deleteIndexes:
"users"
, index:
"zip"
})
创建索引命令
实际上创建索引还有更方便的命令,那就是ensureIndex,比如我们创建一个open和close两个字段的联合索引,就可以用下面的命令:
db.values.ensureIndex({open:
1
, close:
1
})
这个命令会触发索引创建的两个过程,一个是将相应的字段排序,因为索引是按B+树来组织的,要构建树,将数据进行排序后能够提高插入B+树的效率(第二个过程的效率),在日志中,你能看到和下面类似的输出:
Tue Jan
4
09
:
58
:
17
[conn1] building
new
index on { open:
1.0
, close:
1.0
}
for
stocks.values
1000000
/
4308303
23
%
2000000
/
4308303
46
%
3000000
/
4308303
69
%
4000000
/
4308303
92
%
Tue Jan
4
09
:
59
:
13
[conn1] external sort used :
5
files in
55
secs
第二个过程是将排序好的数据插入到索引结构中,构成可用的索引:
1200300
/
4308303
27
%
2227900
/
4308303
51
%
2837100
/
4308303
65
%
3278100
/
4308303
76
%
3783300
/
4308303
87
%
4075500
/
4308303
94
%
Tue Jan
4
10
:
00
:
16
[conn1] done building bottom layer, going to commit
Tue Jan
4
10
:
00
:
16
[conn1] done
for
4308303
records
118
.942secs
Tue Jan
4
10
:
00
:
16
[conn1] insert stocks.system.indexes 118942ms
除了日志中的输出外,你还可以通过在终端执行currentOp命令来获取当前操作线程的相关信息,如下例:
> db.currentOp()
{
"inprog"
: [
{
"opid"
:
58
,
"active"
:
true
,
"lockType"
:
"write"
,
"waitingForLock"
:
false
,
"secs_running"
:
55
,
"op"
:
"insert"
,
"ns"
:
"stocks.system.indexes"
,
"query"
: {
},
"client"
:
"127.0.0.1:53421"
,
"desc"
:
"conn"
,
"msg"
:
"index: (1/3) external sort 3999999/4308303 92%"
}
]
}
最后一部分就是一个索引构建过程,目前正在执行排序过程,执行到92%。
在后台创建索引
创建索引会对数据库添加写锁,如果数据集比如大,会将线上读写数据库的操作挂起,以等待索引创建结束。这影响了数据库的正常服务,我们可以通过在创建索引时加background:true 的选项,让创建工作在后台执行,这时候创建索引还是需要加写锁,但是这个写锁不会直接独占到索引创建完成,而是会暂停为其它读写操作让路,不至于造成严重的性能影响。具体方法:
db.values.ensureIndex({open:
1
, close:
1
}, {background:
true
})
离线创建索引
无论如何,索引的创建都会给数据库造成一定的压力,从而影响线上服务。如果希望创建索引的过程完全不影响线上服务,我们可以通过将replica sets中的节点先从集群中剥离,在这个节点上添加相应的索引,等索引添加完毕后再将其添加到replica sets中。这只需要保证一个条件,就是创建索引的时间不能长于oplog能够保存日志的时间,否则创建完后节点再上线发现再也无法追上primary了,这时会进行resync操作。
索引备份
我们知道,无论是使用mongodump还是mongoexport命令,都只是对数据进行备份,无法备份索引。我们在恢复的时候,还是需要等待漫长的索引创建过程。所以,如果你希望备份的时候带上索引,那么最好采用备份数据文件的方式。
索引压缩
索引在使用一段时间后,经历增删改等操作,会变得比较松散,从而战用不必要的空间,我们可以通过reindex命令,重新组织索引,让索引的空间占用变得更小。
- MongoDB索引管理
- mongodb-索引管理
- MongoDB数据库的索引管理
- 查看MongoDB索引的使用,管理索引
- MongoDB索引与索引管理详解
- MongoDB 学些 第四节 索引管理
- MongoDB 索引的使用, 管理 和优化
- MongoDB索引管理-索引的创建、查看、删除
- MongoDB索引管理-索引的创建、查看、删除
- 学习MongoDB--(5-2):索引(查看索引的使用,管理索引)
- 学习MongoDB--(5-2):索引(查看索引的使用,管理索引)
- mongodb索引
- MongoDB索引
- MongoDB索引
- MongoDB 索引
- MongoDB 索引
- mongodb 索引
- MongoDB 索引
- 浅谈C#中常见的委托
- wait系统调用解析
- Asp.net 后台调用js方法
- wsprintf swprintf sprintf
- Socket 异步通信
- MongoDB索引管理
- sws_scale 解释
- ios验证身份证是否合法
- Bitmap 处理之不要在UI主线程中处理Bitmap
- C#中对字符串的处理
- 使用华为短信包,发送短信Result=61问题解决
- 微软Imagine Cup 2013大赛中国区CSDN高校俱乐部校区比赛成绩及获奖名单
- Visual C++ 调用 Visual C++写的DLL最简单的方法
- ISO8583 按PBOC要求完成8583信息的组包及解包