•索引详讲
1.创建简单索引
准备数据:
for(var i = 0 ; i<200000 ;i++){
db.books.insert({number:i,name:i+"book"})
}
1.先检验一下查询性能
var start = new Date()
db.books.find({number:65871})
var end = new Date()
end - start
输出结果,可以看到是94秒,
var start = new Date()
> db.books.find({number:65871})
{ "_id" : ObjectId("5b682d28707a6a48fda446f5"), "number" : 65871, "name" : "65871book" }
> var end = new Date()
> end - start
94
2.为number 创建索引
注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。
ensureIndex:创建的是文本索引
createIndex: 为普通索引
1、正序索引, 2、倒序索引,
使用ensureIndex创建的是文本索引
db.books.ensureIndex({number:1})
比如查询最近一段时间;一个月 、一个季度,建议倒序;
db.books.ensureIndex({number:1});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
//使用createIndex 创建索引
db.books.createIndex({"name":1,"age":-1})
3.再执行第一部的代码可以看出有数量级的性能提升 11毫秒
var start = new Date()
>
> db.books.find({number:65871})
{ "_id" : ObjectId("5b682d28707a6a48fda446f5"), "number" : 65871, "name" : "65871book" }
>
> var end = new Date()
>
> end - start
11
createIndex() 接收可选参数,可选参数列表如下:
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。 |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
dropDups | Boolean | 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. |
sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. |
expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 |
v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 |
weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
实例
在后台创建索引:
db.values.createIndex({open: 1, close: 1}, {background: true})
2.索引使用需要注意的地方
1.创建索引的时候注意1是正序创建索引-1是倒序创建索引
2.索引的创建在提高查询性能的同事会影响插入的性能
对于经常查询少插入的文档可以考虑用索引
3.符合索引要注意索引的先后顺序
4.每个键全建立索引不一定就能提高性能呢
索引不是万能的
5.在做排序工作的时候如果是超大数据量也可以考虑加上索引
用来提高排序的性能
3、索引名称
创建索引同时指定索引的名字db.books.ensureIndex({指定索引,索引的名字)
db.books.ensureIndex({name:-1},{name:”bookname”})
4.唯一索引
4.1如何解决文档books不能插入重复的数值
建立唯一索引
db.books.ensureIndex({name:-1},{unique:true})
试验
db.books .insert({name:”1book”})
E11000 duplicate key error collection: foobar.books index: bookname dup key: { : "1
book" }
5.剔除重复值
5.1如果建议唯一索引之前已经有重复数值如何处理。
db.books.ensureIndex({name:-1},{unique:true,dropDups:true})
参数 | 类型 | 描述 |
---|---|---|
background | boolean | 创建索引在后台运行,不会阻止其他对数据库操作 |
unique | boolean | 创建唯一索引,文档的值不会重复 |
name | string | 索引名称,默认是:字段名_排序类型 开始排序 |
sparse | boolean | 过滤掉null,不存在的字段 |
如果存在重复索引,删除重复的数据,只保留一条数据;
6.Hint
6.1如何强制查询使用指定的索引呢?
比如建了四个索引,我指定其中的一个,比如name;
db.books.find({name:"1book",number:1}).hint({name:-1})
指定索引必须是已经创建了的索引
7.Explain
7.1如何详细查看本次查询使用那个索引和查询数据的状态信息
后续完善
8.查看索引
db.books.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "foobar.books"
},
{
"v" : 2,
"key" : {
"number" : 1
},
"name" : "number_1",
"ns" : "foobar.books"
},
{
"v" : 2,
"unique" : true, //唯一索引
"key" : {
"name" : -1 //倒序索引
},
"name" : "bookname", //索引名称
"ns" : "foobar.books" // 数据库
}
]
9、创建符合索引
db.books.createIndex({"name":1, "number":-1})
插入成功
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}
查看一下db.books.getIndexex();
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "foobar.books"
},
{
"v" : 2,
"key" : {
"number" : 1
},
"name" : "number_1",
"ns" : "foobar.books"
},
{
"v" : 2,
"unique" : true,
"key" : {
"name" : -1
},
"name" : "bookname",
"ns" : "foobar.books"
},
{
"v" : 2,
"key" : {
"name" : 1,
"number" : -1
},
"name" : "name_1_number_-1",
"ns" : "foobar.books"
}
]
10、多键索引
11、文本索引
一个集合最多只能创建 一个 文本 索引。
12、2dsphere 索引
13、2d索引 (空间索引)
1.准备数据;
var map = [{
"gis" : {
"x" : 185,
"y" : 150
}
},{
"gis" : {
"x" : 70,
"y" : 180
}
},{
"gis" : {
"x" : 75,
"y" : 180
}
},{
"gis" : {
"x" : 185,
"y" : 185
}
},{
"gis" : {
"x" : 65,
"y" : 185
}
},{
"gis" : {
"x" : 50,
"y" : 50
}
},{
"gis" : {
"x" : 50,
"y" : 50
}
},{
"gis" : {
"x" : 60,
"y" : 55
}
},{
"gis" : {
"x" : 65,
"y" : 80
}
},{
"gis" : {
"x" : 55,
"y" : 80
}
},{
"gis" : {
"x" : 0,
"y" : 0
}
},{
"gis" : {
"x" : 0,
"y" : 200
}
},{
"gis" : {
"x" : 200,
"y" : 0
}
},{
"gis" : {
"x" : 200,
"y" : 200
}
}]
for(var i = 0;i<map.length;i++){
db.map.insert(map[i])
}
1.查询出距离点(70,180)最近的3个点
添加2D索引
db.map.createIndex(keypattern[,options])
db.map.ensureIndex({"gis":"2d"},{min:-1,max:201})
默认会建立一个[-180,180]之间的2D索引
db.map.createIndex({"索引名字":"2d"}, {索引范围,min:0,max:200});
db.map.createIndex({"gis":"2d"}, {min:0, max:360});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
查询点(70,180)最近的3个点
db.map.find({"gis":{$near:[70,180]}},{gis:1,_id:0}).limit(3)
2.查询以点(50,50)和点(190,190)为对角线的正方形中的所有的点
db.map.find({"gis":{"$within":{$box:[[50,50],[190,190]]}}},{"_id":0,});
{ "gis" : { "x" : 50, "y" : 50 } }
{ "gis" : { "x" : 50, "y" : 50 } }
{ "gis" : { "x" : 60, "y" : 55 } }
{ "gis" : { "x" : 55, "y" : 80 } }
{ "gis" : { "x" : 65, "y" : 80 } }
{ "gis" : { "x" : 65, "y" : 185 } }
{ "gis" : { "x" : 70, "y" : 180 } }
{ "gis" : { "x" : 75, "y" : 180 } }
{ "gis" : { "x" : 185, "y" : 150 } }
{ "gis" : { "x" : 185, "y" : 185 } }
3.查询出以圆心为(56,80)半径为50规则下的圆心面积中的点
db.map.find({"gis":{"$within":{$center:[[56,80],50]}}},{_id:0, gis:1})
14、hashed indexes
15、索引属性
•索引管理
1.system.indexes
1.1在shell查看数据库已经建立的索引
db.system.indexes.find()
db.system.namespaces.find()
2.后台执行
2.1执行创建索引的过程会暂时锁表问题如何解决?
为了不影响查询我们可以叫索引的创建过程在后台
db.books.ensureIndex({name:-1},{background:true})
3.删除索引
3.1批量和精确删除索引 runCommand({}) 可以执行任意的mongodb命令
db.books.dropIndex( { "number" : 1 } );
db.runCommand({dropIndexes : ”books” , index:”name_-1”})
db.runCommand({dropIndexes : ”books” , index:”*”})