MongoDB索引

        MongoDB提供了许多不同的方法,可以在其中形成索引并将其存储在内存(和磁盘)中。 这些索引中的每一个都有不同的用途,可能仅适用于某些数据类型。 我们来看看这些索引类型。

1、索引类型

1.1    单字段索引

        MongoDB支持所有数据类型中的单个字段索引,并且可以在文档的任何用户定义字段上定义。

        需要注意的是,对于单个字段索引,索引键的排序顺序无关紧要,因为MongoDB可以在任一方向读取索引。

1.2    复合索引

        通常我们需要在多个字段的基础上搜索表/集合,这是非常频繁的。 如果是这种情况,我们可能会考虑在MongoDB中制作复合索引。 复合索引支持基于多个字段的索引,这扩展了索引的概念并将它们扩展到索引中的更大域。

        制作复合索引时要注意的重要事项包括:字段顺序与索引方向。

1.2.1    字段顺序

        文档建立复合索引后,复合索引树会按复合索引里的字段顺序进行排序,如(a,b)索引,会先按a排序,再按b排序。

        复合索引内字段顺序,取决于查询语句的字段排序:

        1)如果我们的查询语句需要对a进行排序,b只是用于覆盖索引,那么建(a,b)索引;也即,如果建(a,b)索引,用a查询可以用上索引,用b查询是用不上索引的,这个也符合复合索引字段的前置优先规则。

        2)如果我们的查询语句需要对b进行排序,a只是用于覆盖索引,那么建(b,a)索引;也即,如果建(b,a)索引,用b查询可以用上索引,用a查询是用不上索引的,这个也符合复合索引字段的前置优先规则。

        3)如果我们的查询语句需要对a和b排序,那么建(a,b)或者(b,a)索引都可以用上索引,但是,这两种索引的效率取决于查询结果对应的a和b数据量。如果,查询出的文档结果集中,a的数量很多,b的数量很少,那么应该使用(b,a)索引,先找少的,再找多的,这样可以减少索引数据检索的范围。另外,查询语句中,a和b写的顺序不影响使用索引的效率,因为mongoDB会自动把查询语句优化,选择先查哪个,后查哪个。

1.2.2    索引方向

        查询语句若涉及到sort排序或者范围查询时,有可能需要指定索引的方向。

        1)sort排序。索引方向跟查询语句的sort排序顺序保持一致,这样,查的时候就可以直接按索引顺序取数据即可。否则,就用不了索引了,因此顺序反了,当然拿不到数据。

        2)范围查询。索引方向会影响范围查询的查询效率,索引数据是按照索引方向的顺序来排列的,我们需要让范围查询需要检索的数据尽可能少。例如,有1、2、3、4、......、10000的数据,范围查询条件是gt(10),如果索引方向是升序,那么只需要检索1~11,即可;如果索引方向是降序,那么需要索引10000~9,这个索引的数据量就大多了。

1.3    全文索引

        MongoDB提供了在文本字段上创建索引的功能,该索引还支持在集合中搜索某些字符串内容。 应注意,这些索引不存储诸如“该”,“一个”,“或”之类的停用词。 在文本索引中,单词仅用于存储根词。 我们可以使用以下查询在字段上创建文本索引:

        db.books.createIndex( { book_name: "text" } )

        文本全文索引是不区分大小写和不区分大小写的。文本索引建立起来的数据仅可进行模糊查询,适合因数据过大无法建立单键索引的词牌。

        一个查询只能指定最多一个$text表达式。不能使用hint()强制指定使用全文搜索。

        MongoDB中文全文索引建立方式与英文的简历几乎相同,是根据词(英文单词)的方式建立的。 如果一个值里面有多个值则需要按空格方式隔开,”张 王” 系统则认为是两个词。MongoDB的中文全文索引沒有想象中的强大。想要实现中文模糊搜素可以用elasticsearch或者Sphinx,或者lucene。

        此外,MongoDB还有全文索引相似度功能,$meta操作符:{score:{$meta:'textScore'}},写在查询条件后面可以返回返回结果的相似度,与sort一起使用,可以对相似度排序,实现搜索结果的关联程度排行。

        全文索引在工作还是经常使用的,比如博客文章的搜索,长文件的关键词搜索,这些都需要使用全文索引来进行。

1.4    内嵌文档索引

        对于文档嵌套的情况,也可以建立内嵌文档的索引,包括两种:

        1)第一种直接对内嵌文档建索引;

        2)第二种对内嵌文档里的Key建索引。

1.5    数据索引(多键索引)

        可以对数组直接建立索引,或者对内嵌文档内部的数组建立索引。

1.6    哈希索引

        这种类型的索引允许我们对内容执行基于哈希的分片。 在这种类型的索引中,键的值被散列。 由于这个原因,这些索引只能支持相等匹配过滤器查询,并且不能在基于范围的查询上工作。

        如果我们想在索引上运行范围查询,我们可能必须在同一个字段上创建多个索引,其中一个可以是常规索引,另一个可以是散列索引。 最后,Hashed索引将浮点字段截断为整数。 应尽可能避免对散列字段使用浮点。

2、索引属性

2.1    唯一索引

        这些索引可以通过规范使其成为唯一的。这样,当要求单个字段索引保持唯一时,它将拒绝该密钥的集合中已存在的值。 MongoDB中的任何索引都可以是唯一的。

        在复合索引中,索引值的唯一性通过与组成复合索引的键对应的值的组合来维持。

        在创建唯一索引的时候,明显感觉比创建单个索引慢很多,这是由于创建的时候需要检查其唯一性。而在所以创建之后发现已经存在两个索引,还有一个就是特殊的_id索引,就是一个唯一索引,只是该索引不能进行删除操作。所以在没有必要的情况下可以直接使用mongoDB的_id的值,如果是自己去实现的话在插入的时候会检查唯一性,会有性能影响(MongoDB的字段生成主键与ES的主键非常的类似,会有性能优化)。

        由于会检查唯一性,所以在创建索引的时候可能会失败,或者在创建好之后插入文档的时候也可能失败。在创建唯一索引之前可以使用聚合API查询一下是否存在重复的数据,若是数据非常重要则需要先备份和数据的预处理。否则可以使用dropDups可选项,将只保留一条重复的数据。如下:

    db.user.ensuerIndex({"username":1},{"unique":true , "dropDups":true});   # 不管怎么样,一定先备份数据

    还有一点需要注意的是,唯一索引的存储值不能超过1024KB,否则不会报错也不会受唯一约束。并且很难对问题进行排查。

2.2    稀疏索引

        稀疏索引仅包含具有索引字段的文档的条目,即使索引字段包含空值也是如此。索引会跳过缺少索引字段的任何文档。配合唯一索引使用,即可实现对存在的字段才使用唯一索引。

        a、间隙索引就是创建索引的索引列在某些文档上列不存在,导致索引存在间隙。 

        b、间隙索引在创建时应指定选项:{ sparse: true } 

        c、间隙索引列上可以指定唯一性约束

索引使用注意事项:

1)数据不超万条时,不需要使用索引。性能的提升并不明显,而大大增加了内存和硬盘的消耗。

2)查询数据超过表数据量30%时,不要使用索引字段查询。实际证明会比不使用索引更慢,因为它大量检索了索引表和我们原表。

3)数字索引,要比字符串索引快的多,在百万级甚至千万级数据量面前,使用数字索引是个明确的选择。

4)把你经常查询的数据做成一个内嵌数据(对象型的数据),然后集体进行索引;

5)线上环境建立索引,一定要加 {background: true},不然会卡死mongoDB进程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352