MongoDB索引(索引基本操作)

Wesley13
• 阅读 290

转自:http://blog.csdn.net/congcong68/article/details/46955115

一、简介

     在MongoDB建立索引能提高查询效率,只需要扫描索引只存储的这个集合的一小部分,并只把这小部分加载到内存中,效率大大的提高,如果没有建立索引,在查询时,MongoDB必须执行全表扫描,在数据量大时,效率差别就很明显,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。

    索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。索引项的排序支持高效的相等匹配和基于范围的查询操作。

   从mongoDB 3.0开始ensureIndex被废弃,使用 createIndex创建索引。

   创建索引的语法:

[sql]  view plain copy

  1. db.collection.createIndex(keys,options)

  

 参数

类型

描述

keys

document

一个包含该字段的字段和值对的文档,该文档的索引键和该值描述该字段的索引类型。对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为1。

MongoDB支持几种不同的索引类型,包括文本,空间,和哈希索引。查看更多信息的索引类型。

options

document

在创建索引的时的限制条件

二、 索引的基本操作

       我们先插入10w条记录

[sql]  view plain copy

  1.  for(var i=0;i<1000000;i++){
  2. .       db. orders.insert({
  3.          "onumber" : i,
  4.          "date" : "2015-07-02",
  5.          "cname" : "zcy"+i,
  6.           "items" :[ {
  7.                    "ino" : i,
  8.                   "quantity" : i,
  9.                   "price" : 4.0
  10.             },{   
  11.                   "ino" : i+1,
  12.                   "quantity" : i+1,
  13.                   "price" : 6.0
  14.              }  
  15.           ]  
  16.     })  
  17. }

  

    1.      默认索引

          存储在MongoDB集合中的每个文档(document)都有一个默认的主键“_id“,如果我们在添加新的文档时,没有指定“_id“值时,MongoDB会创建一个ObjectId值,并创建会自动创建一个索引在“_id“键上,默认索引的名称是”_id_“,并无法删除,如下面的命令查看:

[sql]  view plain copy

  1. >db.orders.getIndexes()

  

         MongoDB索引(索引基本操作)

     2.       查看索引信息

              返回一个数组,该数组保存标识和描述集合上现有索引的文档列表,可以查看我们是否有对某个集合创建索引,并创建哪些索引,方便我们管理。

               语法:

[sql]  view plain copy

  1. >db.collection.getIndexes()

  

      3.      创建单列索引

              我们对文档单个字段创建索引或者对内嵌文档的单个字段创建索引

              语法:

[sql]  view plain copy

  1. db.collection.createIndex({field:boolean} })

  

                   boolean:对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为1。

              (1)创建

                      例子:

[sql]  view plain copy

  1. >db.orders.createIndex({cname:1})

        

                         MongoDB索引(索引基本操作)

                  我们对orders集合创建了cname索引,默认的索引名称是”cname_1“

               (2)根据条件查询文档,并查看查询效率怎么样

                       例子:

[delphi]  view plain copy

  1. > db.orders.find({"cname":"zcy100000"})

                    我们查询orders 集合根据条件cname为zcy100000的文档

                    我们测试有建索引和没建索引在1000000条文档执行查询的效率怎么样,我们这边先使用explain()函数,下一篇我们介绍

                   我们这边先介绍几个参数

                             1) n:当前查询返回的文档数量。

                             2)millis:当前查询所需时间,毫秒数。

                             3)indexBounds:当前查询具体使用的索引

                      例子:

[sql]  view plain copy

  1. > db.orders.find({"cname":"zcy100000"}).explain()

                       1)没建索引时,查询条件cname为zcy100000的文档

                          MongoDB索引(索引基本操作)

                       返回一个记录,花费1006毫秒,没使用到索引

                      2)有建索引,查询条件cname为zcy100000的文档

                             MongoDB索引(索引基本操作)

                             返回一个记录,花费82毫秒,有使用到cname索引

                            我们结果是相差很大的,有建索引字段,查询效率比较高,在大数据时,差别更明显。

        (3)查询和排序组合使用

               我们查询集合cname大于zcy100的文档并对onumber进行降序排序

               例子:

[sql]  view plain copy

  1. >db.orders.find({"cname":{$gt:"zcy1000"}}).sort({"onumber":1}).explain()

                     MongoDB索引(索引基本操作)

               执行出现错误:

               "$err" : "Runner error:Overflow sort stage buffered data usage of 33554456 bytes exceeds internal limit of 33554432 bytes",

                  我们的内存只有33554432字节,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。

                  我们对onumber创建索引

[sql]  view plain copy

  1. > db.orders.createIndex({onumber:-1})

  

               MongoDB索引(索引基本操作)

                  MongoDB索引(索引基本操作)

              这次我们在执行时,可以正常执行,已经减少了内存的缓存的数据

   4.       创建组合索引

             我们可以同时对多个键创建组合索引

            语法:   

[sql]  view plain copy

  1. db.collection.createIndex({field1:boolean, field2:boolean } })

  

       说明:

            db.collection.createIndex({a:1,b:1,c:1 } })

           我们对a、b、c进组合创建索引,支持查询时会用到索引的几种:

          1)      a

          2)      a,b

          3)      a,b,c

     这三中的查询条件,会使用到索引

      (1)      创建组合索引

         我们同时对onumber和cname进行组合索引

       例子:

[sql]  view plain copy

  1. >db.orders.createIndex({cname:1,onumber:-1})

  

          索引存储在一个易于遍历读取的数据集合中,存储的数据

         {_id:..,"onumber" : 2, "date" : "2015-07-02", "cname" : "zcy1"})

         {_id:..,"onumber" : 1, "date" : "2015-07-02", "cname" : "zcy1"})

         {_id:..,"onumber" : 1, "date" : "2015-07-02", "cname" : "zcy2"})

        (2) 查询

            1)我们对cname和onumber作为查询条件时

              例子:

[sql]  view plain copy

  1. >db.orders.find({"cname":{$gt:"zcy1000"},"onumber":2000}).explain()

                   MongoDB索引(索引基本操作)

                 我们查询条件cname大于zcy1000并且onumber等于2000的数据,我们用explain()查询索引使用情况

             2)我们只用两个索引其中一个作为查询时

                第一种情况:我们条件只使用"cname":{$gt:"zcy1000"}作为查询条件

               例子:

[sql]  view plain copy

  1. >db.orders.find({"cname":{$gt:"zcy1000"}}).explain()

                    MongoDB索引(索引基本操作)

              会使用到索引,符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到索引的第一种。

           第二种情况:我们条件只使用"onumber":2000作为查询条件

           例子: 

[sql]  view plain copy

  1. > db.orders.find({"onumber":2000}).explain()

                  MongoDB索引(索引基本操作)

          不会使用到索引,不符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到几种。

    (3)查询和排序组合使用

       我们查询集合cname大于zcy100的文档并对onumber进行降序排序

         例子:

[sql]  view plain copy

  1. >db.orders.find({"cname":{$gt:"zcy1000"}}).sort({"onumber":1}).explain()

       执行出现错误:

          "$err" : "Runner error:Overflow sort stage buffered data usage of 33554456 bytes exceeds internal limit of 33554432 bytes",

         sort时,不会使用到索引,不符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到几种。

           总结:我们在使用组合索引时,查询时会用到组合索引的前端的几种组合。

                    我们对a、b、c进组合创建索引,支持查询时会用到索引的几种:

                    1)      a

                   2)      a,b

                   3)      a,b,c

    5.      内嵌文档的索引

            我们对内嵌文档创建索引时,跟基本文档创建索引一样

          语法:

[sql]  view plain copy

  1. db.collection.createIndex({field:boolean} })

  

            field说明:以“.“来指明内嵌文档的路径

       (1)      单列的内嵌文档的索引创建

              例子:

[sql]  view plain copy

  1. >db.orders.createIndex({"items.info":1})

             MongoDB索引(索引基本操作)

         我们orders集合下的内嵌items集合的info字段创建索引

          我们以items.info字段作为查询条件,并使用索引的情况

        例子:

[sql]  view plain copy

  1. >db.orders.find({"items.info":{$lt:100}}).explain()

           MongoDB索引(索引基本操作)

           我们查询items.info小于100的数据

   (2)      组合的内嵌文档的索引的创建

        我们对内嵌文档创建组合索引时,跟基本文档创建组合索引一样

         语法:

[sql]  view plain copy

  1. >db.collection.createIndex({field1:boolean, field2:boolean } })

  

          例子:

[sql]  view plain copy

  1. >db.orders.createIndex({"items.info":1, "items. quantity":-1})

  6.      删除索引

      我们对已经创建的索引进行删除,可以针对具体的集合中索引进行删除,也可以对所有的集合中的所有索引删除

   (1)具体索引名称删除索引

         语法:

[sql]  view plain copy

  1. db.collection.dropIndex(index)

       删除具体的索引,根据索引名称删除,如果不知道索引的名称,可以通过db.collection.getIndexes()查看索引名称

       例子:

[sql]  view plain copy

  1. > db.orders.dropIndex("cname_1")

        MongoDB索引(索引基本操作)

     我们删除cname字段的索引,现在只剩下onumber字段索引

           MongoDB索引(索引基本操作)

 (2)删除集合中所有索引

       语法:

[sql]  view plain copy

  1. db.collection.dropIndexes()

  

        例子:

[sql]  view plain copy

  1. > db.orders.dropIndexes()

  

         MongoDB索引(索引基本操作)

       我们对集合中的索引都删除,我们删除cname字段的索引和onumber字段索引,现在只剩默认的_id字段索引,索引我们在使用时,要谨慎,以免把集合中的索引都删除。

      (3)对dropIndexes方法,我们还有一种用法,可以指定集合的具体索引的删除

         例子:

[sql]  view plain copy

  1. > db.runCommand({"dropIndexes":"orders","index":"cname_1"})

           MongoDB索引(索引基本操作)

          我们删除cname字段的索引,现在只剩下onumber字段索引

  总结:

            在MongoDB建立索引能提高查询效率,但在MongoDB新增、修改效率上比较慢

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
2年前
P2P技术揭秘.P2P网络技术原理与典型系统开发
Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这