8.索引的创建

来源:互联网 发布:大数据 去伪存真 编辑:程序博客网 时间:2024/06/08 17:48

索引

1.创建简单索引

准备数据
向books集合中插入20w条数据:

> for(var i=0;i<200000; i++){db.books.insert({number:i,name:i+"book"})}

1.1 先测试一下没有创建索引之前的查询效率

var start = new Date();db.books.find({number:65535})var end = new Date();end-start

结果:328ms 与机器性能相关

1.2 为number键创建索引

//为number键创建正序索引db.books.ensureIndex({number:1})

1.3 再次测试查询效率

var start = new Date();db.books.find({number:65535})var end = new Date();end-start

结果:47ms !! 这是一个数量级的提升

2.索引使用需要注意的地方

2.1创建索引的时候注意

1:创建正序索引 -1:创建倒序索引

2.2 索引的创建在提高查询性能的同时,会影响插入的性能

对于经常查询少查询的文档可以考虑使用索引

2.3 符合索引要注意索引的先后顺序

问:为每个键创建索引是不是性能就会提高?

索引不是万能的(要合理创建索引)

在做排序工作的时候如果是超大数据量也可以考虑加上索引
用来提高排序的性能

3.索引的名称

3.1 使用VUE来查看索引的名称

这里写图片描述

3.2 创建索引的用时指定索引的名字

db.books.ensureIndex({name:-1},{name:”bookname”})

4.唯一索引

4.1如何避免文档books插入重复数值?

建立唯一索引

db.books.ensureIndex({name:-1},{unique: "bookname"})

测试:
尝试再次插入重复数值

db.books.insert({name:1book”})

出现错误:
这里写图片描述

4.2建立唯一索引之前已经有了重复的数值,该如何处理?

在建立索引的时候有一个可选项:建立索引同时剔除重复值
操作:

db.books.ensureIndex({name:-1},{unique:ture,dropDups:true})

5.Hint 使用指定的索引进行查询

如何强制使用指定的索引进行查询呢?

db.books.find ({name:1book”,number:1}).hint({name:-1})

指定索引必须是已经创建了的索引
否则出现如下错误:
这里写图片描述

6.Explain 使用

如何详细查看本次查询使用哪个索引和查询数据的状态信息?
调用explain()方法

> db.books.find({number:65535}).explain(){        "cursor" : "BtreeCursor number_1",        "isMultiKey" : false,        "n" : 1,        "nscannedObjects" : 1,        "nscanned" : 1,        "nscannedObjectsAllPlans" : 1,        "nscannedAllPlans" : 1,        "scanAndOrder" : false,        "indexOnly" : false,        "nYields" : 0,        "nChunkSkips" : 0,        "millis" : 0,        "indexBounds" : {                "number" : [                        [                                65535,                                65535                        ]                ]        },        "server" : "itcast01:27017",        "filterSet" : false}“cursor”:”BtreeCursor number_1” 使用的索引“nscanned”:1    查到几个文档“millis”:0  查询耗时 

2.索引的管理

1. 使用shell查看数据库已经建立的索引system.indexes

> db.system.indexes.find(){ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "admin.admin" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "admin.text" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "admin.user" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "admin.persons" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "admin.books" }{ "v" : 1, "key" : { "number" : 1 }, "name" : "number_1", "ns" : "admin.books" }

2.后台执行

执行创建索引的过程会暂时锁表的问题如何解决?
为了不影响查询,我们可以让索引的创建过程在后台完成

db.books.ensureIndex({name:-1},{background:true})

3.删除索引

精确删除索引

db.runCommand({dropIndexes : "books" , index:”name_-1})

或者:

db.COLLECTION.dropIndex("IndexName")

批量删除索引

db.runCommand({dropIndexes: "集合名称",index: "*"})

3.空间索引

MongoDB提供了强大的空间索引可以查询出一定范围内的地理坐标

这里写图片描述

准备数据

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    db.map.insert(map[i])}

添加2D索引

db.map.ensureIndex({"gis":"2d"},{min:-1,max:201})

1.查询出距离点(70,180)最近的3个点

默认会建立一个[-180,180]之间的2D索引 查询点(70,180)最近的3个点

db.map.find({"gis":{$near:[70,180]}},{gis:1,_id:0}).limit(3){ "gis" : { "x" : 70, "y" : 180 } }{ "gis" : { "x" : 75, "y" : 180 } }{ "gis" : { "x" : 65, "y" : 185 } }

2.查询以点(50,50)和点(190,190)为对角线的正方形中的所有的点

db.map.find({gis:{"$within":{$box:[[50,50],[190,190]]}}},{_id:0,gis:1}){ "gis" : { "x" : 185, "y" : 150 } }{ "gis" : { "x" : 75, "y" : 180 } }{ "gis" : { "x" : 70, "y" : 180 } }{ "gis" : { "x" : 65, "y" : 185 } }{ "gis" : { "x" : 65, "y" : 80 } }{ "gis" : { "x" : 55, "y" : 80 } }{ "gis" : { "x" : 60, "y" : 55 } }{ "gis" : { "x" : 50, "y" : 50 } }{ "gis" : { "x" : 50, "y" : 50 } }{ "gis" : { "x" : 185, "y" : 185 } }

3.查询出以圆心为(56,80)半径为50规则下的圆心面积中的点

db.map.find({gis:{$within:{$center:[[56,80],50]}}},{_id:0,gis:1}){ "gis" : { "x" : 55, "y" : 80 } }{ "gis" : { "x" : 50, "y" : 50 } }{ "gis" : { "x" : 50, "y" : 50 } }{ "gis" : { "x" : 60, "y" : 55 } }{ "gis" : { "x" : 65, "y" : 80 } }
0 0