8.索引的创建

本文介绍MongoDB中索引的创建与使用方法,包括简单索引、复合索引及唯一索引,并演示如何利用空间索引来实现地理坐标查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

索引

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 } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值