wordpress个人下载网站模板下载,推广网站的广告怎样做,php网站开发过程,白银市建设局网站首页一、索引简介 再来老生常谈一番#xff0c;什么是索引呢#xff1f;数据库索引与书籍的索引类似。有了索引就不需要翻整本书#xff0c;数据库可以直接在索引中查找#xff0c;在索引中找到条目以后#xff0c;就可以直接跳转到目标文档的位置#xff0c;这能使查找速度提… 一、索引简介 再来老生常谈一番什么是索引呢数据库索引与书籍的索引类似。有了索引就不需要翻整本书数据库可以直接在索引中查找在索引中找到条目以后就可以直接跳转到目标文档的位置这能使查找速度提高几个数量级。 然而使用索引是有代价的对于添加的每一个索引每次写操作插入、更新、删除都将耗费更多的时间。这是因为当数据发生变动时MongoDB不仅要更新文档还要更新集合上的所有索引。因此MongoDB限制每个集合上最多只能有64个索引。通常在一个特定的集合上不应该拥有两个以上的索引。于是挑选合适的字段建立索引非常重要。 索引基数基数cardinality就是集合中某个字段拥有不同值的数量。比如 gender 字段基数一般就男女 2个而已而像 mobile 这样的字段基数就会特别大。 通常来讲一个字段的基数越高这个字段上的索引就越有用。这是因为索引能够迅速将搜索范围缩小到一个比较小的结果集。对于低基数的字段索引通常无法排除掉大量可能的匹配。假设我们在gender上有一个索引需要查找名为Susan的女性用户。通过这个索引只能将搜索空间缩小到大约50%。 tips在关系型数据库中类似 gender 这样的字段可以使用位图索引。 索引原理浅析我们以一个索引 {age : 1 username : 1} 来看看索引在MongoDB 中是如何存储的大致是这个样子 每一个索引条目都包含一个age字段 和 username字段并且指向文档在磁盘中的存储位置。注意这里的 age 严格的按照升序排序并且相同的 age 对应的 username 也严格的按照升序排序。 来看个例子 db.users.find({age : 21}).sort({username : -1}) 这个索引对于这个查询来说是非常高效的因为它可以马上定位到 age 21 的位置并且age 21 中的 username 已经是排序好的。 tips排序方向并不重要MongoDB可以在任意方向上对索引进行遍历。tips查询中的字段顺序无关紧要MongoDB 会自动找出可以使用索引的字段而无视查询的字段顺序。 $操作符如何使用索引有一些查询完全无法使用索引也有一些查询能够比其他查询更高效地使用索引。 $where无法使用索引。$nin无法使用索引。$exists无法使用索引。因为在索引中不存在的字段和null字段的存储方式是一样的查询必须遍历每一个文档检查这个值是否真的为null还是根本不存在。$ne可以使用索引但并不是很高效。因为必须遍历整个索引条目才能找到结果的文档。$not能够使用索引但通常不知道如何使用索引从而退化成全表扫描。$or能够使用索引但是$or 查询会将 or 的条件拆分成多个独立的查询然后再将结果合并在一起。这是很低效的不建议用。建议用 $in 取代 $or 。 设计多键索引的时候要记得要把基数大的字段放在索引的前面因为这样能更快缩小查询的范围。 二、索引类型 复合组合索引复合索引就是一个建立在多个字段上的索引。如果查询中有多个排序方向或者查询条件中有多个键复合索引就非常有效。 db.userInfo.ensureIndex({age:1,age:1}) 进行多键排序时索引的方向尤为重要。尽量做到多键排序的方向和复合索引的方向是一致的因为这能很大的避免在内存中进行排序的运算。tips相互反转(在每个方向上都乘以-1)的索引是等价的{age : 1 user name : -1}适用的查询与{age : -1 username : 1}是完全一样的。 复合索引具有双重功能而且对不同的查询可以表现为不同的索引。如果有一个{age :1 username : 1}索引age字段会被自动排序就好像有一个{age : 1}索引一样。因此这个复合索引可以当作{age : 1}索引一样使用。 唯一索引唯一索引可以确保集合的每一个文档的指定键都有唯一值。我们熟悉的 _id 索引就是一个唯一索引但它不能被删除而其他唯一索引是可以删除的。 db.users.ensureIndex({username : 1}, {unique : true}) 定义了唯一索引后这个键就不允许插入重复的值了否则会抛异常。tipsA 字段不存在 和 A 字段为 null 是互斥的 在已有的集合上创建唯一索引可能会报错因为集合中可能已经有重复的值了。在极少数情况下可能希望直接删除重复的值。创建索引时使用dropDups选项如果遇到重复的值第一个会被保留之后的重复文档都会被删除。 db.users.ensureIndex({username : 1}, {unique : true, dropDups : true}) 稀疏索引在有些情况下你可能希望唯一索引只对包含相应键的文档生效。如果有一个可能存在也可能不存在的字段但是当它存在时它必须是唯一的这时就可以将unique和sparse选项组合在一起使用创建唯一稀疏索引。注意MongoDB中的稀疏索引sparse index与关系型数据库中的稀疏索引是完全不同的概念。基本上来说MongoDB中的稀疏索引只是不需要将每个文档都作为索引条目。并且稀疏索引并不一定是唯一的。 db.ensureIndex({email : 1}, {unique : true, sparse : true}) 当某个查询使用了稀疏索引就不会返回不包含这个字段的文档。因为稀疏索引并没有把每个文档都作为索引条目。 覆盖索引如果你的查询只需要查找索引中包含的字段那就根本没必要获取实际的文档。当一个索引包含用户请求的所有字段可以认为这个索引覆盖了本次查询。所以尽可能使用投射筛选返回的字段比如 {_id:0,age:1} 等来实现覆盖索引。 三、索引管理 新建索引普通索引 db.userInfo.ensureIndex({name:1},{name,MyIndex})1 表示按照name进行升序-1 表示按照name进行降序。默认的索引以 key1_1_key2_-1 这样的方式命名可以手动指定索引的名字如上。 对象索引 可以对整个对象建立索引或者对对象的某个元素使用索引。 db.users.ensureIndex({loc : 1})只有在进行与对象字段顺序完全匹配的子文档查询时比如db.users.find({loc :{ip : 123.456.789.000 city : Shelbyville state :NY}}})查询优化器才会使用loc上的索引。 db.users.ensureIndex({loc.city : 1})有涉及到对象city的查询都会使用这个索引。 数组索引 对数组建立索引实际上是对数组的每个元素建立一个索引条目。比如一个文档中的数组字段有20个元素那么该文档就拥有了20个索引条目所以对数组字段的索引建立要慎重。 删除索引db.userInfo.dropIndexes(name_1) 删除指定索引 db.userInfo.dropIndexes() 删除除了_id 以外的所有索引 操作索引获取当前索引列表db.userInfo.getIndexes() hint 暴力选择某种索引db.userInfo.find({name:zhangsan,birthday:1989-3-2}).hint({name:1,birthday:1}) 强制使用全表扫描db.userInfo.find({birthday : {$lt :1989-3-2}}).hint({$natural : 1}) 索引分析函数explainMongoDB 3.0前 和 MongoDB 3.0后存在很大的差异这里只简单说明下如果想详细了解的话可以关注该作者的文章 MongoDB 3.0 前db.driverLocation.find({areaCode:350203}).explain() cursor表扫描方式 basicCursor顺序查找 nscanned浏览了多少文档 n最终返回了几个文档 millis总共耗时了多少毫秒 scanAndOrder是否必须在内存中对数据进行排序 MongoDB 3.0 后db.driverLocation.find({areaCode:350203}).explain(executionStats) executionTimeMillis该query的整体查询时间 nReturned查询返回的条目 totalKeysExamined索引扫描条目 totalDocsExamined文档扫描条目 转载于:https://www.cnblogs.com/jmcui/p/8757299.html