----------mongo系列文章-------------
----------mongo系列文章-------------
摘要
mongo 的索引非常强大,和关系型数据库索引没什么区别。这里主要介绍mongo索引基本知识和mongo本人在索引上的犯的错。
索引种类
单字段索引
复合索引复合索引各个字段的顺序应该是精确匹配字段(=xxx),排序字段(避免在内存中排序,使用index排序),范围查询字段
如db.book.find().sort() 可以很好的列出查询执行计划。总共有四个重要参数:executionTimeMills:查询执行的时间nReturned: 返回的文档数totalKeysExamined: 索引扫描数totalDocsExamined: 文档扫描数
当然希望nReturned数目=totalKeysExamined不扫描文档。(后面不挂着数据,index及数据)
或者nReturned = totalKeysExamined = totalDocsExamined如果有排序,为了不让排序在内存中进入,在nReturned = totalDocsExamined的基础上,totalKeysExamined可以大于nReturned。对于大数据量的内存排序会非常消耗性能
如果我们创建一个复合索引是db.book.ensureIndex()这时候nReturned = totalKeysExamined = totalDocsExamined。因为查询会用到index,不需要额外的文档扫描。但是会有SORT stage,即在内存中排序,在大数据量的情况下内存排序是很慢的。
尝试加一个index,在排序字段放在扫描字段前面db.book.ensureIndex()这时候发现mongo选择了新的index
且执行计划中有reject SORT排序
这时候nReturned = totalDocsExamined
但是如果你的查询不是范围查询。而是精确匹配字段。那还是使用原来的index。因为这时候排序字段用到了index查询,不需要SORT阶段了
多键索引如array索引https://docs.mongodb.com/manual/core/index-multikey/
多键索引是没法查一个数组全部匹配的,会先查第一个元素,后面的会使用filter
$elemMatch
这个查询和 }的区别,后者是只要数组中任意一个字段满足其他一个条件即可,比如第一个字段满足gt:9,第二个字段满足lt:11那么也认为是满足条件。所以使用索引时,只能使用到一个边界条件。
在联合索引中只允许有一个array字段。但是因为mongo是free schema的。可以是不同的字段,只要一个document中只有一个array就行了,在不同的document中可以是不同字段
注意
当一个collection上面有多个index某个查询可能命中多个index,这时候mongo是如何选择索引的呢。
当有一个复合索引
这时候有一个新的查询可以用到已经创建的复合索引。这时候你会不会单独在创建一个索引呢。优势是这个查询也很快,缺点是多了一个index,减弱了插入性能。
这个可能需要衡量前两个字段过滤掉了多少数据,phone这个字段占剩下数据量的多少来决定需要创建什么样的index.
mongo 中有一个名字叫scalar(标量字段)就是非array,非embedded document这样的字段。针对这些字段的索引与关系型数据库并无差别,无需特殊处理觉得这篇分享就有点过于强调阅读mongo源码来解决的问题的重要性,因为这个就可以通过上述分析找到root causehttps://yq.aliyun.com/articles/74635?utmcampaign=wenzhang&utmmedium=article&utmsource=QQ-qun&201752&utmcontent=m_19216
array index
mongo 可以对array建立index,注意是将index中的每个元素都作为index key,进行索引。所以对array建立index一定要十分小心,很容易导致index size 很大。另外mongo支持指定array某一列进行查询。
shard key index
表中有数据 表中有数据再创建shard key,需要首先创建对应的index,才能去创建shard key
表中无数据 表中无数据,创建shard key的同时,mongo会自动创建一个对应字段的index
会自动创建index
mongo index VS cassandra secondary index
1.query 过程cassandra query,首先根据partitioner key去找对应partition,partition中的数据是按照clustering key排序的。注意是按照clustering key排序的,clustering key这个字段 不是index。
mongo(sharding cluster) query,首先根据给定的shard key去找在哪个节点上,然后将请求发送到此节点。进行查找。如果你的query case是
而shard key是name。此外再单独为address建立一个index。这时候你的query其实是命中的address 的单字段index。而不是预想的已经将name数据过滤了。这点和cassandra有很大的不同
2.范围
cassandra secondary index 是local的,在每个节点上。 mongo sharding cluster 环境,index也是在各个shard上独立创建的。
参考
领取专属 10元无门槛券
私享最新 技术干货