Mongodb主从复制/ 副本集/分片集群对比
MongoDBA
mongodb - createdCollectionAutomatically的意思
详细查看从下面链接: https://docs.mongodb.com/manual/reference/command/createIndexes/#output
createdCollectionAutomatically
的意思是:是否创建了新的collection,如果是false,表示没有创建,如果是true,表示创建了新的colletion
例子:运行 db.myCollection.createIndex({"address":1})
,如果myCollection不存在的话,结果如下所示:
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1, // 命令运行前索引的数量
"numIndexesAfter" : 2, // 命令允许后的索引数量
"ok" : 1
}
MongoDB支持索引种类
MongoDB和其他DBMS一样,也支持索引机制,可以通过索引优化查询,避免全表扫描。MongoDB支持多种索引。
从以上可以看出,MongoDB与MySQL类似,MySQL支持的索引MongoDB也几乎都支持,而且MongoDB索引同样是使用b+树存储。不过与MySQL不同的时,MongoDB建立索引的时候,可以指定正序还是逆序。
这是MongoDB的默认索引,每个文档插入集合时,都会自动生成一个_id字段,MongoDB在该字段上创建唯一索引。与MySQL的主键概念类似,插入文档时可以手动指定,也可以由MongoDB的ObjectID自动生成,如果手动指定重复,则插入失败。
MongoDB为集合文档上的任意一个字段都可以创建索引,可以指定升序或者降序。包括
与MyQSL类似,MongoDB也支持组合索引,可以对文档的多个字段创建一个组合索引,多个字段的顺序很重要,底层存储按照前后顺序排列,同样满足最左前缀匹配原则。
例如创建userId-name两个字段的索引,可以匹配userId的查询,也可以匹配userId-name的查询,但无法匹配name或者name-userId的查询。
创建组合索引时同样可以手动指定按照升序还是降序排列,在普通索引时,升序还是降序不重要,因为MongoDB可以在任一方向遍历索引,而组合索引字段的升序还是降序会影响排序是否走索引。
例如创建name升序-age降序的组合索引,当遇到name升序-age降序的查询和name降序-age升序的查询都可以走索引,而遇到name升序-age升序或者name降序-age降序的查询时则无法走索引。即查询的每个字段顺序必须要与索引排序一致或都相反,这样MongoDB会选择从正向遍历索引或者反向遍历索引从而走索引查询。
为保存数组值的字段建立索引,MongoDB为数组中的每个元素创建一个索引。这些多键索引支持对数组字段的有效查询。可以在既包含标量值(例如字符串,数字)又包含嵌套文档的数组上构造多键索引。
需要注意的是分片键不能是多键索引,Hash索引也不能多键,多键索引也不能对数组覆盖查询。
现在大多数软件开发都与地理位置有关,例如美团,滴滴的定位等LBS相关项目,一般存储每个地点的经纬度的坐标,如果想要查询周围场所,则需要建立索引提高效率。
MongoDB在1.4版本引入了地理空间索引。MongoDB支持两种地理空间索引:
MongoDB也提供了一种text索引类型,类似于MySQL的全文索引,该类型支持在集合中搜索字符串内容。
相比于B+树logn的查询时间复杂度,哈希的O(1)时间复杂度更适合查询,而由于Hash不适合范围查询的特性,导致目前主流存储数据结构采用b+树。但与MqSQL类似,MongoDB同样提供了哈希索引。
MongoDB为了支持基于散列的分片,MongoDB提供了一种散列索引类型,该索引类型对字段值的散列进行索引。这些索引在其范围内具有更随机的值分布,但仅支持相等匹配,而不能支持基于范围的查询。
部分索引仅索引集合中符合指定过滤器表达式的文档。通过索引集合中文档的子集,部分索引具有较低的存储需求,并降低了索引创建和维护的性能成本。
创建部分索引时,还需要指定过滤表达式,只为符合条件的数据创建索引,可以有效减少冷数据索引的存储空间和维护。
索引的稀疏属性可确保索引仅包含具有索引字段的文档的条目。索引会跳过没有索引字段的文档。
您可以将稀疏索引选项与唯一索引选项结合使用,以防止插入索引字段具有重复值的文档,并跳过缺少索引字段的索引文档。
TTL索引是MongoDB可以使用的特殊索引,可以在一定时间后自动从集合中删除文档。对于某些类型的信息(例如机器生成的事件数据,日志和会话信息),它们仅需要在数据库中保留有限的时间,这是理想的选择。
与MySQL一样,MongoDB同样支持覆盖索引,即查询结果被索引覆盖,查询速度就会提升很多,因为这样数据可以直接从索引拿,不用再次回表查询。
索引交集是MongoDB在2.6版的新功能。
MongoDB可以使用索引的交集来完成查询。对于指定复合查询条件的查询,如果一个索引可以满足查询条件的一部分,而另一个索引可以满足查询条件的另一部分,则MongoDB可以使用两个索引的交集来满足查询。使用复合索引还是使用索引交集是否更有效取决于特定查询和系统。
使用Mongo函数: db.collection.totalIndexSize() 来获取索引的大小
可以使用帮助函数 db.collection.totalIndexSize() 来检查索引的大小,返回的数值单位是字节:
> db.collection.totalIndexSize()
4294976499
上述例子展示了一个几乎4.3GB的索引。为了确保索引与内存相适应,您不仅需要有那么多足够可用的内存用于索引,还要有足够的内存用于剩下的 working set 。还有请记住:
如果您拥有且使用多个集合,您必须考虑所有集合的所有索引的大小。所有的索引和工作集(working set)在同一时刻必须能与内存相适应。
MongoDB 3.4:使用索引来排序查询结果
在MongoDB中,排序操作可以通过从索引中按照索引顺序获取文档的方式来保证结果的有序性。如果查询计划器(planner)无法从索引中得到排序顺序,那么它将需要在内存中排序结果。相比于不使用索引的排序操作,使用索引会有更好的性能。此外,如果 不使用 索引的排序操作使用了超过32M的内存,那么操作会终止。
如果一个递增或递减索引是单键索引,那么在该键上的排序操作可以是任意方向。
For example, create an ascending index on the field a for a collection records:
db.records.createIndex( { a: 1 } )
索引可以支持在 a 上的递增排序:
db.records.find().sort( { a: 1 } )
索引也支持如下在 a 上的递减排序,通过以相反的顺序遍历索引的方式:
db.records.find().sort( { a: -1 } )
Create a compound index to support sorting on multiple fields.
您可以指定在索引的所有键或者部分键上排序。但是,排序键的顺序必须和它们在索引中的排列顺序 一致 。例如,索引 { a: 1, b: 1 } 可以支持排序 { a: 1, b: 1 } 但不支持 { b: 1, a: 1 } 排序。
此外,sort中指定的所有键的排序顺序(例如递增/递减)必须和索引中的对应键的排序顺序 完全相同, 或者 完全相反 。例如,索引 { a: 1, b: 1 } 可以支持排序 { a: 1, b: 1 } 和排序 { a: -1, b: -1 } ,但 不支持 排序 { a: -1, b: 1 } 。
如果排序的键符合索引的键或者 前缀 ,那么MongoDB可以使用索引来排序查询结果。复合索引的前缀是指被索引键的子集,由一个或多个排在最开始的键组成。
例如,在集合 data 上创建一个复合索引:
db.data.createIndex( { a:1, b: 1, c: 1, d: 1 } )
那么,该索引的前缀如下:
{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }
如下查询和排序操作可以使用索引前缀来排序查询结果。这些操作不需要在内存中对结果集排序。
例子 |
索引前缀 |
---|---|
db.data.find().sort( { a: 1 } ) | { a: 1 } |
db.data.find().sort( { a: -1 } ) | { a: 1 } |
db.data.find().sort( { a: 1, b: 1 } ) | { a: 1, b: 1 } |
db.data.find().sort( { a: -1, b: -1 } ) | { a: 1, b: 1 } |
db.data.find().sort( { a: 1, b: 1, c: 1 } ) | { a: 1, b: 1, c: 1 } |
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } ) | { a: 1, b: 1 } |
Consider the following example in which the prefix keys of the index appear in both the query predicate and the sort:
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )
在这种情况下,MongoDB可以使用索引按照sort指定的顺序来获取文档。如例子中所示,在查询条件中的索引前缀可以和在sort中出现的前缀不一样。
索引也支持使用非前缀的键来排序。在这种情况下,对于索引中排列在排序键的前面的所有键,查询语句中必须包含针对它们的 相等匹配 的条件。
例如,集合 data 有如下索引:
{ a: 1, b: 1, c: 1, d: 1 }
如下操作可以使用索引来排序:
例子 |
索引前缀 |
---|---|
db.data.find( { a: 5 } ).sort( { b: 1, c: 1 } ) | { a: 1 , b: 1, c: 1 } |
db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } ) | { a: 1, b: 1, c: 1 } |
db.data.find( { a: 5, b: { $lt: 3} } ).sort( { b: 1 } ) | { a: 1, b: 1 } |
如最后一个操作所示,只有索引中那些排列在排序键 前面 的键必须在查询语句中有相等匹配条件;其他索引键则可以指定其他匹配条件。
如果查询语句 没有 对排列在排序键前面或者与之有所重叠的前缀键指定相等匹配条件,那么操作将 不会 有效使用索引。例如,如下操作指定了排序 { c: 1 } ,但是查询语句并没有对前缀键 a 和 b 指定相等匹配:
db.data.find( { a: { $gt: 2 } } ).sort( { c: 1 } )
db.data.find( { c: 5 } ).sort( { c: 1 } )
These operations will not efficiently use the index { a: 1, b: 1, c: 1, d: 1 } and may not even use the index to retrieve the documents.
MongoDB 创建索引以支持查询
当索引包含了查询的所有键时,索引可以支持该查询。查询会扫描索引而不是集合。创建可以支持查询的索引会带来极大的查询性能提升。
本文描述了创建支持查询的索引的策略。
如果您在某个集合上只查询某个单键,那么您可以在这个集合上创建一个单键索引。例如,您可能在 product 集合的 category 键上创建索引:
db.products.createIndex( { "category": 1 } )
如果您有时需要查询某个键,而有时又需要查询同样的键和额外的键,那么和创建单键索引相比,创建复合索引会是更高效的选择。MongoDB都会使用复合索引来处理这两种请求。例如,您可能会在 category 和 item 键上创建索引:
db.products.createIndex( { "category": 1, "item": 1 } )
这允许您有两种选择。您可以只查询 category 或者同时查询 category 和 item 。一个在多个键上创建的 复合索引 可以支持那些搜索被索引键的 “前缀” 子集的查询。
例子
在某集合上有如下索引:
{ x: 1, y: 1, z: 1 }
它可以支持如下索引支持的查询:
{ x: 1 }
{ x: 1, y: 1 }
在某些情况下,前缀键的索引可能会有更好的查询性能:例如,如果 z 是一个很大的数组。
索引 { x: 1, y: 1, z: 1 } 也支持许多如下索引支持的查询:
{ x: 1, z: 1 }
此外, { x: 1, z: 1 } 索引还有其它用途。给定如下查询:
db.collection.find( { x: 5 } ).sort( { z: 1} )
索引 { x: 1, z: 1 } 同时支持查询和排序操作,但是索引 { x: 1, y: 1, z: 1 } 只支持查询。参见 使用索引来排序查询结果 了解更多关于排序的详细信息。