• Mongodb Manual阅读笔记:CH7 索引


    7索引

    Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作
    Mongodb Manual阅读笔记:CH3 数据模型(Data Models)
    Mongodb Manual阅读笔记:CH4 管理
    Mongodb Manual阅读笔记:CH5 安全性
    Mongodb Manual阅读笔记:CH6 聚合
    Mongodb Manual阅读笔记:CH7 索引
    Mongodb Manual阅读笔记:CH8 复制集
    Mongodb Manual阅读笔记:CH9 Sharding

     

    对于频繁使用查询,索引提供了高性能。

    7索引... 1

    7.1索引介绍... 2

    7.1.1 索引类型... 3

    7.1.1.1 默认_id. 3

    7.1.1.2 单字段索引(Single Field)3

    7.1.1.3复合索引(Compound Index)3

    7.1.1.4 Multikey Index. 3

    7.1.1.5地理空间索引... 4

    7.1.1.6文本索引... 4

    7.1.1.7 Hash索引... 4

    7.1.2索引属性... 4

    7.1.2.1唯一索引... 4

    7.1.2.2稀疏索引... 4

    7.2 索引概述... 5

    7.2.1索引类型... 5

    7.2.1.1索引类型特性... 5

    7.2.1.2索引类型文档... 5

    7.2.2索引属性... 8

    7.2.2.1 TTL索引... 8

    7.2.2.2唯一索引... 8

    7.2.2.3稀疏索引... 8

    7.2.3创建索引... 9

    7.2.3.1后台构建... 9

    7.2.3.2 删除重复... 9

    7.2.3.3 索引名... 10

    7.3索引教程... 10

    7.3.1创建索引... 10

    7.3.1.1创建一个索引... 10

    7.3.1.2创建复合索引... 10

    7.3.1.3创建唯一索引... 10

    7.3.1.4创建稀疏索引... 11

    7.3.1.5创建hash索引... 11

    7.3.1.6在复制集上创建索引... 11

    7.3.1.7后台创建索引... 11

    7.3.1.8创建老式索引... 12

    7.3.2索引管理教程... 12

    7.3.2.1删除所有... 12

    7.3.2.2重建索引... 12

    7.3.2.3管理在建索引... 12

    7.3.2.4返回所有索引... 12

    7.3.2.5评估索引的使用... 13

    7.3.3地理空间索引教程... 13

    7.3.4文本查询教程... 13

    7.3.4.1启动文本查询... 13

    7.3.4.2创建文本索引... 13

    7.3.4.3查询文本... 14

    7.3.4.4指定语言... 15

    7.3.4.5为文本索引创建名字... 16

    7.3.4.6使用权重控制查询... 17

    7.3.4.7限制扫描行数... 17

    7.3.4.8创建文本覆盖索引... 18

    7.3.5索引策略... 18

    7.3.5.1创建索引支持查询... 18

    7.3.5.2为排序的查询提供顺序... 19

    7.3.5.3保证索引都在内存中... 19

    7.3.5.4保证查询的选择性... 19

    7.4索引指南... 19

     

    7.1索引介绍

    索引是查询高效的解决方案。如果没有索引,那么mongodb会扫描整个collection。索引是一个b树结构,保存了collection中的部分数据。

    当查询可以使用某个索引的时候,mongodb会使用索引来限制输入文档的个数。如:

    创建了索引,只保证少部分的数据被扫描。

    对于排序,如果有索引可用,可以不需要排序后在输出。索引本来就是有顺序的。

    对于覆盖,当查询的标准和projection都在这个索引里面,查询会直接从索引中返回,不会扫描collection

    7.1.1 索引类型

    Mongodb提供了不同的索引类型来支持数据查询。

    7.1.1.1 默认_id

    如果应用程序没有给_id指定特别的值,mongod会自动在_id 上创建索引。

    _id是一个唯一索引,当相同的_id 被插入就会报错

    7.1.1.2 单字段索引(Single Field)

    在一个字段为key创建的索引叫做单字段索引。

    7.1.1.3复合索引(Compound Index)

    如果在多个字段为key那么就是复合索引,如:

    7.1.1.4 Multikey Index

    如果一个字段是一个数组,在这个字段上面创建索引。Mongodb会自己决定,是否要把这个索引建成Multikey Index

    7.1.1.5地理空间索引

    Mongodb提供了2个地理索引,2d index2sphere Index

    7.1.1.6文本索引

    文本索引不保存指定的stop wordstem word只保留词根。

    7.1.1.7 Hash索引

    Hash索引时对key进行hash计算然后创建索引,目前只支持等号运行,不支持区间。

    7.1.2索引属性

    7.1.2.1唯一索引

    索引的唯一属性,会拒绝key的重复值插入

    7.1.2.2稀疏索引

    稀疏属性保证了索引只包含有字段值的(对于mongo来说null也是一个值)

    7.2 索引概述

    本节介绍mongotypes,配置选项和索引的特性。

    7.2.1索引类型

    MongoDB提供了很多不同的索引类型

    7.2.1.1索引类型特性

    所有索引在Mongodb中都是B树结构,可以有效的支持相等的匹配和区间查询,也可以以索引顺序直接输出

    索引顺序

    MongoDB索引有顺序和逆序2中排序方式,对于单字段索引而言,顺序和逆序是没什么区别的。对于复合索引而言,有时候顺序转化是不行的。

    索引冗余(Redundant Indexes)

    一个查询只能使用一个索引,但是对于or,每个子句都可以使用其他的索引

    7.2.1.2索引类型文档

    本节介绍索引,单字段索引,复合索引,Multikey Indexes,地理空间索引,文本索引,Hash索引

    单字段索引

    Mongodb默认所有的collection都有个单字段索引,_id

    如果有一个friends collection,:

    { "_id" : ObjectID(...),

    "name" : "Alice"

    "age" : 27

    }

    可以使用一下语句在name上创建索引:

    db.friends.ensureIndex( { "name" : 1 } )

    案例

    _id索引_id上的索引是默认创建的,并且不能删除而且是唯一的。如果不显示的插入值,_idObjectID类型长度为12字节。

    在子文档字段上的索引:你可以在一个子文档上创建索引,如:

    {"_id": ObjectId(...)

    "name": "John Doe"

    "address": {

    "street": "Main"

    "zipcode": 53511

    "state": "WI"

    }

    }

    然后再address上创建索引:

    db.people.ensureIndex( { "address.zipcode": 1 } )

    在子文档上创建索引:同时也可以对整个子文档创建索引:

    {

    _id: ObjectId("523cba3c73a8049bcdbf6007"),

    metro: {

    city: "New York",

    state: "NY"

    },

    name: "Giant Factory"

    }

    db.factories.ensureIndex( { metro: 1 } )

    db.factories.find( { metro: { city: "New York", state: "NY" } } )

    匹配成功然后返回上面的文档,但是一下的查询就匹配不了:

    db.factories.find( { metro: { state: "NY", city: "New York" } } )

    复合索引

    key字段大于1个的时候都被叫做复合索引。

    创建方法:

    db.products.ensureIndex( { "item": 1, "stock": 1 } )

    对已经hash索引的字段不能创建复合索引。并且复合索引字段个数最多31

    复合索引的排序,是先对第一个字段排序,然后第二个依次类推。

    查询可以使用复合索引里面的前缀,都可以使用到这个索引。

    排序顺序

    复合索引的本身的排序顺序会影响查询是否可以使用索引的顺序。

    如索引:db.events.ensureIndex( { "username" : 1, "date" : -1 } )

    db.events.find().sort( { username: 1, date: -1 } )

    db.events.find().sort( { username: -1, date: 1 } )

    都可以使用这个索引的顺序,但是一下查询使用不了:

    db.events.find().sort( { username: 1, date: 1 } )

    Mutikey Index

    Multikey索引允许MongoDB返回在数组上的查询。Mongodb自己决定是否对数组创建multikey index

    Multikey支持数组值和嵌套文档

    限制

    复合索引和Multikey索引的相互作用:当你创建复合索引的multikey,只能有一个字段是数组,如果建立了复合索引,在2个字段上都已经是数组,那么插入就会回绝。

    Hash索引hase索引不能被multikey索引兼容。MongoDB会折叠子文档,然后计算整个的hash值。

    在嵌入文档数组中的索引:你可以使用在子文档数组上创建multikey索引。

    地理空间索引和查询

    手册p326

    文本索引

    文本索引是区分大小写的,并且可以是字符串,和字符串数组。

    要使用text索引,和使用text命令要先启用text搜索。

    创建文本索引:创建文本索引,如:

    db.reviews.ensureIndex( { comments: "text" } )

    文本索引或删除stop word和后缀。文本索引可以覆盖查询。

    存储需求和性能花费:有以下几个花费和需求:

    1.       文本索引修改了collection中的空间分配的方法为usePowerOf2Sizes

    2.       文本索引比较大。为每个单词创建一个索引项

    3.       创建文本索引和创建multikey索引很类似,会花费大量的时间

    4.       在创建大的文本索引时,要确保有足够的文件描述符(Unix ulimit设置)

    5.       文本索引会影响插入的吞吐量,要为每一个单词索引

    6.       另外,文本索引不保存短语或者信息中近似的单词

    文本查询mongodb提供了text命令来执行文本搜索。搜索过程如下:

             1.在索引创建和text命令执行的时候先标记和提取查询的term

             2.为匹配到的文档分配一个分数,分数决定的文档和关键字之间的关联

    默认text命令返回前100关联比较强的文档。

    Hash索引

    Hash索引维护了索引字段的hash值,如果是子文档,那么会对真个子文档做hash计算。Hash索引支持shard collection作为shard key

    Mongodb可以在相等匹配的时候使用hash索引,区间匹配的时候不能使用。

    如果已经在这个字段上创建了hash索引,那么不能再在上面创建复合索引,但是可以创建单字段索引。

    7.2.2索引属性

    Mongodb除了支持多种索引之外,还支持不同的索引属性。

    7.2.2.1 TTL索引

    创建了TTL索引,Mongodb会根据TTL索引自动删除collection的文档。比较适用于事件数据,日志,回话信息。

    这个索引有一下几个限制:

             1.不支持复合索引

             2.索引字段必须是时间类型

             3.如果是一个数组,当数组内的时间任意一个过期,就算过期

    7.2.2.2唯一索引

    唯一索引会回绝所有重复的键值。

    db.addresses.ensureIndex( { "user_id": 1 }, { unique: true } )

    如果在复合索引上创建唯一,那么复合索引里面的key的组合是唯一的,而不是单个key唯一。

    文档插入,如果没有key,那么会被当null存,如果有一个唯一索引在这个字段上,又插入一个没有key的文档,那么就会报错。你可以再加稀疏索引来过滤这些空值。

    7.2.2.3稀疏索引

    稀疏索引只包含了有这个字段的文档,即便这个字段是null值,当文档没有这个值的时候,就不会被保存到稀疏索引中。如:

    { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }

    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

    db.scores.ensureIndex( { score: 1 } , { sparse: true } )

    db.scores.find().sort( { score: -1 } )

    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

    查询只会返回有score的文档。

    稀疏索引和唯一索引:稀疏索引和唯一索引一起使用可以达到,关系型数据库中建的效果(不能为空,不能重复)。

    7.2.3创建索引

    Mongodb创建索引通过db.collection.ensureIndex()方法,

    7.2.3.1后台构建

    默认创建索引都会把其他数据库操作block,对于一个运行比较长的索引创建,可以考虑后台运行。

    db.people.ensureIndex( { zipcode: 1}, {background: true} )

    后台创建默认为false

    特性

    2.4版本之后,mongod可以支持多个索引在后台同时创建。

    后台创建之后数据库还可以正常运行,不会被堵塞,但是当前创建索引的回话会被堵塞,直到创建完成。如果后台创建了索引,那么就不能执行其他的管理操作。

    性能

    后台索引创建是使用递增的方式,比通常的(前台)索引创建要慢,如果索引比内存大,那么会更加大的慢。

    为了避免出现性能问题,最好在数据库设计阶段就确定好索引的索引设计。

    secondary创建索引

    primary使用后台索引创建,到了secondary之后会变成前台创建。所有的索引操作在secondary中都会被block

    secondary中创建大索引最好的方式是,重启secondarystandalone状态,然后创建索引,创建完之后再加入到复制集,然后赶上primary之间的滞后。然后在下一个secondary上创建。当所有的secondary建好之后,切换primary,然后重启变为standalone,创建索引。

    当在secondary上创建索引的时候,oplog需要有足够的空间。

    7.2.3.2 删除重复

    collection中有重复键,那么就无法创建唯一索引,可以使用dropDups选项强制删除索引,会报存第一个key,接下来的重复的key的文档都会被删除。

    如:

    db.accounts.ensureIndex( { username: 1 }, { unique: true, dropDups: true } )

    默认这个选项为false

    7.2.3.3 索引名

    默认索引名和key,排序顺序有关,如:db.products.ensureIndex( { item: 1, quantity: -1 } )的索引名为:item_1_quantity_-1,可以使用以下来修改指定索引名:

    db.products.ensureIndex( { item: 1, quantity: -1 } , { name: "inventory" } )

    7.3索引教程

    本节介绍,索引创建,索引管理,地理空间索引,文本搜索,索引策略

    7.3.1创建索引

    7.3.1.1创建一个索引

    Mongodb默认会在_id上创建一个索引,并允许用户在任意字段上创建索引

    在单个字段上创建索引

    可以使用ensureIndex()在单个字段上创建索引。

    如:db.people.ensureIndex( { "phone-number": 1 } )

    额外考虑:如果collection太大,可以考虑后台创建,让数据库处于可用状态,不会被堵塞。

    7.3.1.2创建复合索引

    复合索引好处,是提供了索引覆盖,可以直接从索引中返回数据。

    创建复合索引db.collection.ensureIndex( { a: 1, b: 1, c: 1 } )

    额外考虑:如果collection太大,可以考虑后台创建,让数据库处于可用状态,不会被堵塞。

    7.3.1.3创建唯一索引

    唯一索引只是索引的一个属性

    db.collection.ensureIndex( { a: 1 }, { unique: true } )

    一般唯一索引和稀疏索引一起使用:db.collection.ensureIndex( { a: 1 }, { unique: true, sparse: true } )

    也可以在复合索引上创建唯一属性。

    删除重复:可以删除重复的key

    db.collection.ensureIndex( { a: 1 }, { unique: true, dropDups: true } )

    7.3.1.4创建稀疏索引

    稀疏索引和非稀疏索引不同,非稀疏索引会包含所有的文档,如果没有这个字段用null填充,稀疏索引如果文档没有这个字段,那么就不会为这个文档index

    db.collection.ensureIndex( { a: 1 }, { sparse: true } )

    7.3.1.5创建hash索引

    Hash索引时对索引字段进行hash计算,只能用户等号的匹配,不能用于区间匹配。

    db.collection.ensureIndex( { _id: "hashed" } )

    考虑hash索引可以在任何字段上创建,包括子文档,会把所有的的内容计算hash,不支持multikey

    7.3.1.6在复制集上创建索引

    后台创建索引在secondary会变成前台,前台创建索引会把复制blocksecondary会在primary创建了索引之后再创建,如果在shard中有复制集,那么会现在shardprimary上创建,然后再secondary上创建。

    注意点

    需要保证oplog有足够的空间,用来保存延迟。

    过程

    1.关闭一个Secondary:先关闭一个secondary然后以启动不加—replSet选项,使用不同的端口运行。

    2.创建索引:使用ensure创建索引

    3.重启mongod:创建完之后重启mongod加上选项—replSet修改到原来的端口。

    4.在所有secondary上创建索引:每个secondary根据以上1-3步创建索引

    5.primary上创建索引二选一:

             a.先在primary在上是有后台创建索引

             b.然后关闭primary,让别的secondary变成primary,在通过1-3步创建索引。

    在后台创建索引,会比前台创建索引时间长,并且紧凑性比较差,并且会影响primary写入性能。

    7.3.1.7后台创建索引

    前台索引创建会block数据,后台索引创建可以让数据库任然可用,在后台索引创建时,数据库申请读写锁不会被获取。

    db.collection.ensureIndex( { a: 1 }, { background: true } )

    7.3.1.8创建老式索引

    手册page346

    7.3.2索引管理教程

    本节介绍对索引的管理:删除所有,重建索引,管理在创建的索引,返回所有索引,评估索引的使用

    7.3.2.1删除所有

    可以使用dropIndex()方法来删除索引,db.accounts.dropIndex( { "tax-id": 1 } )

    返回{ "nIndexesWas" : 3, "ok" : 1 }

    nindexesWas表示删除之前的索引个数,

    可以使用db.collection.dropIndex()来删除collection下的所有索引。

    7.3.2.2重建索引

    使用db.collection.reIndex()方法来重建collection下的所有索引。

    7.3.2.3管理在建索引

    可以使用db.curentOp()msg字段会指明是否在创建索引,进度。如果不想再创建可以使用db.killop来停止创建。

    7.3.2.4返回所有索引

    索引的元数据存放在system.indexex下面

    获取collection下的索引

    db.people.getIndexes()

    获取数据库下的所有索引

    db.system.indexes.find()

    7.3.2.5评估索引的使用

    查询性能能够很好的指明索引的使用

    操作

    使用explain返回执行计划:在cursor下有个explain查看查询执行计划,其中包含了使用的索引。

    使用hint:使用hint来强制使用索引

    db.people.find( { name: "John Doe", zipcode: { $gt: 63000 } } } ).hint( { zipcode: 1 } )

    使用报表

    serverStatus的输出indexCountersscannedscanAndOrder

    collStats的输出totalIndexSizeindexSizes

    dbStats的输出dbStats.indexesbStats.indexSize

    7.3.3地理空间索引教程

    手册p349

    7.3.4文本查询教程

    本节介绍,启动文本查询,创建文本索引,查询文本,指定语言,为文本索引创建名称,使用权重控制查询结果,限制没扫描的文档,创建覆盖索引

    7.3.4.1启动文本查询

    文本查询现在还是beta版本,一下特性:

    1.需要先启动文本查询

    2.如果要为shard或者复制集启动文本查询,要在每个mongod中都启动

    mongod --setParameter textSearchEnabled=true

    也可以在配置文件中设置textSearchEnable

    7.3.4.2创建文本索引

    可以在多个包含字符串或者字符串数组上面创建文本索引

    指定字段

    db.collection.ensureIndex(

    {

    subject: "text",

    content: "text"

    })

    为所有字段创建索引

    为所有是字符串的字段创建索引可以使用,通配符($**

    db.collection.ensureIndex(

    { "$**": "text" },

    { name: "TextIndex" }

                                         )

    7.3.4.3查询文本

    按组查询(Search For a Term

    db.quotes.runCommand( "text", { search: "TOMORROW" } )

    文本是大小写敏感的,使用text命令查询。

    匹配任意一个查询组

    db.quotes.runCommand( "text", { search: "tomorrow largo" } )

    查询包含tomorrow或者largo的文档

    短语匹配

    db.quotes.runCommand( "text", { search: ""and tomorrow"" } )

    这个可以用来匹配and tomorrow短语

    查询的时候有短语和独立的组时,短语和组之间使用and,组和组之间使用or

    db.quotes.runCommand( "text", { search: ""and tomorrow"" } )

    类似于(corto OR largo OR tomorrow) AND ("and tomorrow")

    Tomorrow来至于短语。

    匹配非某个单词之外的

    db.quotes.runCommand( "text" , { search: "tomorrow -petty" } )

    匹配tomorrow,但是不包含petty

    限制匹配的结果集

    默认text命令会返回100个文档,可以使用limit来限制返回

    db.quotes.runCommand( "text", { search: "tomorrow", limit: 2 } )

    指定返回结果集的列

    Text命令中可以使用project来控制返回的列,1返回,0不返回

    db.quotes.runCommand( "text", { search: "tomorrow",

    project: { "src": 1 } } )

    使用其他的查询条件过滤

    Text命令的filter选项提供了这个功能。之间是and关系

    db.quotes.runCommand( "text", { search: "tomorrow",

    filter: { speaker : "macbeth" } } )

    指定特定的语言查询

    语言决定了stop wordstem word

    db.quotes.runCommand( "text", { search: "amor", language: "spanish" } )

    文本查询的输出

    文本查询的结果以文档的方式输出

    7.3.4.4指定语言

    为文本索引指定默认语言

    如果不填默认语言,语言为英语。如果要指定不同的语言可以在创建索引的时候指定。

    db.collection.ensureIndex(

    { content : "text" },

    { default_language: "spanish" }

    )

    创建多语言的文本索引

    在文档中指定语言

             1.如果文档保存一个language的字段,默认创建索引的时候会以这个字段为语言,来覆盖默认的英文

             2.如果语言字段没有language字段,而是别的字段,那么在索引创建的时候,使用language_override指向这个字段。

    包含language字段

             { _id: 1, language: "portuguese", quote: "A sorte protege os audazes" }

    { _id: 2, language: "spanish", quote: "Nada hay más surreal que la realidad." }

    { _id: 3, language: "english", quote: "is this a dagger which I see before me" }

             db.quotes.ensureIndex( { quote: "text" } )

             如果文档里面有language,创建索引使用这个语言

             如果没有,则使用英文。

    db.quotes.runCommand( "text", { search: "que", language: "spanish" } )

    因为在西班牙语上面questop word 所以匹配不到任何东西。

    指定一个字段作为语言

             可以使用language_override选项上指定字段作为语言

             { _id: 1, idioma: "portuguese", quote: "A sorte protege os audazes" }

    { _id: 2, idioma: "spanish", quote: "Nada hay más surreal que la realidad." }

    { _id: 3, idioma: "english", quote: "is this a dagger which I see before me" }

    db.quotes.ensureIndex( { quote : "text" },

    { language_override: "idioma" } )

             1.如果包含idioma字段,那么以这个字段里面的语言作为语言

             2.如果没有用英语

    7.3.4.5为文本索引创建名字

    默认文本索引创建好后,mongo会自动为这个索引创建一个名字

    db.collection.ensureIndex(

    {

    content: "text",

    "users.comments": "text",

    "users.profiles": "text"

    }

    )

    "content_text_users.comments_text_users.profiles_text"

    当然也可以指定索引名

    db.collection.ensureIndex(

    {content: "text",

    "users.comments": "text",

    "users.profiles": "text"

    },

    {name: "MyTextIndex"}

    )

    7.3.4.6使用权重控制查询

    默认text命令根据分数(scores)从高到低来匹配文档。对于文本索引来说,权重就表示这个字段和其他字段对于查询组来说的重要性。

    默认所有的索引字段的权重都是1,可以在创建索引的时候调整

    db.blog.ensureIndex(

    {

    content: "text",

    keywords: "text",

    about: "text"

    },

    {

    weights: {

    content: 10,

    keywords: 5,

    },

    name: "TextIndex"

    }

    )

    7.3.4.7限制扫描行数

    就是用索引来现在扫描行数

    { _id: 1, dept: "tech", description: "a fun green computer" }

    { _id: 2, dept: "tech", description: "a wireless red mouse" }

    { _id: 3, dept: "kitchen", description: "a green placemat" }

    { _id: 4, dept: "kitchen", description: "a red peeler" }

    { _id: 5, dept: "food", description: "a green apple" }

    { _id: 6, dept: "food", description: "a red potato" }

    db.inventory.runCommand( "text", {

    earch: "green",

    filter: { dept : "kitchen" }

    })

    db.inventory.ensureIndex({

    dept: 1,

    description: "text"

    })

    因为会扫描过滤特定的字段kitchen,然后创建一个符合索引把dept放在前面。

    1.排序索引必须在文本索引的前面

    2.只会对符合prefix的进行索引

    3.不能再有multikey索引或者地理空间索引

    4.text命令必须要办filter,并且使用等号条件。

    这样的话指定的dept会限制扫描的行数

    7.3.4.8创建文本覆盖索引

    1.添加text到排序索引中

    2.使用text命令的时候使用project限制字段。

    db.collection.ensureIndex( { comments: "text",username: 1 } )

    db.quotes.runCommand( "text", { search: "tomorrow",project: { username: 1,_id: 0}})

    7.3.5索引策略

    当设计索引的时候,要考虑读写的比例,内存,查询的类型。

    在创建索引的时候,要知道所有的查询,虽然索引有性能的消耗,但是对查询的效果是很明显的。

    要验证索引是否还有用,哪些运行的最好,如果这个索引没用了,那么请干掉。

    7.3.5.1创建索引支持查询

    当所有覆盖的时候mongo获取扫描索引,而不是从collection中要数据。

    如果所有的查询使用相同的单个key创建单字段索引

    如果你的索引只对一个key进行查询那么创建一个单字段索引。

    为不同的查询创建复合索引

    复合索引有多个key组成,主要复合prefix,都可以使用到复合索引。

    创建覆盖索引

    覆盖索引是为了让mongo不再去扫描collection中的数据

    1.所有的查询中的字段都要在索引中

    2.所有结果返回的字段也要在索引中

    这样效率比较高,因为索引要不再内存中,要不就是在磁盘中但是是顺序的。

    使用explain()中的indexOnly如果为true那么就是覆盖的,否则就不是

    7.3.5.2为排序的查询提供顺序

    可以使用索引里面的排序,为查询提供了很好的性能。

    如果索引时一个覆盖索引,并且查询时索引的prefix,并且前面是使用相等的匹配,那么就可以使用索引的排序。或者排序时覆盖索引的prefix,也可以使用索引的排序。

    explain()返回中如果scanAndOrderfalse说明可以使用索引顺序

    7.3.5.3保证索引都在内存中

    使用db.collection.totalIndexSize()函数查看索引大小,保证加上workset之后比物理内存小。如果有多个collection,那么要看所有的索引大小和workset都可以同时在内存中。

    只保存当前数据在内存中

    有些索引时不需要全部都在内存中的,只要保证最常用的在内存中的就可以了。

    7.3.5.4保证查询的选择性

    选择性是使用索引限制返回行数的能力,低选择性的索引对查询本身就没有什么很大的好处。可以让多个低选择性的字段组合成复合索引,来提高选择性,或者低选择性的字段和高选择性的字段组合成复合索引。

    低选择性可能比查询整个collection还要慢。

    7.4索引指南

    手册p374

  • 相关阅读:
    Ⅲ:作业
    Ⅱ:python入门
    Auth模块
    django中间件
    Django的cookie以及session
    form组件
    Django Ajax
    Django模板层3和ajax初始
    聚合/分组 查询 事务
    Django ORM常用模块
  • 原文地址:https://www.cnblogs.com/Amaranthus/p/3574058.html
Copyright © 2020-2023  润新知