链接地址: http://quentinXXZ.iteye.com/blog/2125433
内容主要来自《 MongoDB The Definitive Guide 2nd Edition》
最基本的建索引命令如下:
db.users.ensureIndex({"username" : 1})
根据username建立索引。1表示升序存储。
MonogDB每个一个collection最多可建64个索引。
利用hint可指定使用哪个索引。
db.users.find({"age" : {"$gte" : 21, "$lte" : 30}}).
... sort({"username" : 1}).
... hint({"username" : 1, "age" : 1}).
采用.hint({"username" : 1, "age" : 1})扫描量变大,但排序变快
组合索引
db.users.find({"age" : {"$gte" : 21, "$lte" : 30}}).
... sort({"username" : 1}).
... limit(1000).
... hint({"age" : 1, "username" : 1}).
... explain()['millis']
用时2031 ms
> db.users.find({"age" : {"$gte" : 21, "$lte" : 30}}).
... sort({"username" : 1}).
... limit(1000).
... hint({"username" : 1, "age" : 1}).
... explain()['millis']
用时181ms
所以官方建议使用{"sortKey" : 1, "queryCriteria" : 1}的索引方式定义组合索引,即将排序条件放在前,查询条件字段放在后,因为大多数应用并不要求返回所有符合结果,只要满足条件的结果就够了(大多实际应用都会使用limit)。
索引的升降序方向只在用需要根据多键进行排序才有意义。{"age" : 1}的索引,对{"age" : -1}或者{"age" : 1}的排序来说性能是一样的。
索引覆盖(covered indexes)
与关系型数据的索引索引覆盖的概念基本相同,可以避免回表查询。
注意的是如果你的索引字段是包含数组的,那么该索引将无法做到索引覆盖,这与数组在索引中的具体存储方式有关。即使你的查询结果不需要该数组字段,你依然无法做到索引覆盖。
$操作符如何使用索引
无法使用索引的情况:
1、当使用“ $where"进行查询时,是用不到索引的。
2、检测Document的某个键是否存在( {"key" : {"$exists" : true}} ),也是无法使用索引的。因为对于索引来说不存在与null这两种状态的表示是相同的。
官方建议:将用于精确查询的字段放在索引前面,用于范围查询的字段放索引后面。
注意,如下查询
db.foo.find({"$or" : [{"x" : 123}, {"y" : 456}]}) 如果x与y单独索引都有,则两个索引都会用到,分别查询,再去重。P93
所以尽可能使用in,不要使用or.
索引内嵌文档与数组
以下一个嵌套文档的例子
{
"username" : "sid",
"loc" : {
"ip" : "1.2.3.4",
"city" : "Springfield",
"state" : "NY"
}
对这样的文档,我们可以只对city建立索引db.users.ensureIndex({"loc.city" : 1}),也可以对loc建立索引db.users.ensureIndex({"loc" : 1})。
注意,对整个子文档loc建索引只会对完全匹配整个子文档的查询有帮助。
Index on array
对数组字段建索引,其实是对数组的每一个元素建索引,所以如果一篇post有20条comment,就会有20条索引项。这使得对索引的维护代价变得更加的昂贵。还有对数组原数的索引,并不会保存这些元素的位置信息,所以你无法使用通过索引来实现类似“comments.4”这种方式的定位。
Index Cardinality(区分度)
例如性别,不应用作索引,因为它的index cardinality(区分度)太低。利用索引区分出找到特定性名的项后,还要去回表查询近50%的条目。
尽量将索引建立在那些区分度高的字段上,或者将区分度较高的字段,放在组合索引的前面。
关于Explain
Explain是monogdb的重要性能分析工具。
> db.users.find({"age" : 42}).explain()
{
"cursor" : "BtreeCursor age_1_username_1",
"isMultiKey" : false,
"n" : 8332,
"nscannedObjects" : 8332,
"nscanned" : 8332,
"nscannedObjectsAllPlans" : 8332,
"nscannedAllPlans" : 8332,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 91,
"indexBounds" : {
"age" : [
[
42,
42
]
],
"username" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "ubuntu:27017"
}
cursor:cursor会显示使用哪个索引,如果为BasicCursor,表示未使用索引,大多数使用索引的查询会使用BtreeCursor。
millis: 如果MongoDB尝试了多种执行方案(mongoDB有Plan Race的策略决定使用哪种方案), "millis" 体现的是花费的总时间,而不是最佳方案的执行时间。
Index entries are described by "nscanned" . The number of documents scanned is reflected in nscannedObjects:扫描的文档数
"nscanned" : 如果使用索引,指查看过的索引数。如果是对表扫描,就是指检查过的文档数。
IndexOnly:是否索引覆盖
"scanAndOrder" : 是存在内存中对结果作排序。(应避免出现)
If MongoDB had to sort results in memor
The Query Optimizer
Plan race.:第一个返回100个结果的方案成为“winner”,其它方案停止执行。
When not to index
当你要返回的集合占总数的比例越来越大时,索引的作用也就越来越小。因为这会涉及两次查询,一次查index,一次回表。
例如,db.entries.find({"created_at" : {"$lt" : hourAgo}}),当数据量增大,可能返回结果会很多。如果你希望直接作表扫描以表的自然顺序返回结果的话,可以使用hint {"$natural" : 1}。
db.currentOp()可以查看当前操作 。
唯一索引
db.users.ensureIndex({"username" : 1}, {"unique" : true})
具有唯一索引的键,就会有唯一约束。“_id”的唯一索引会自动建立无须指定。
有些情况下,有些量可能无法被索引,而monogdb不返回任何警告。所有的字段都必须小于1024个字节(其中包括字段名和值和命名空间),才能含到索引里。All fields must be smaller than 1024 bytes to be included in an index. 所以,超过1024bytes(书说8KB,应该是指8Kb吧?)大小的键不会受到唯一索引的约束,可以插入多个同样的8KB长的字串,因这些不会被索引。
组合唯一索引,对usernmae 和age建立组合索引。两个字段都完全相同,才会违返唯一约束。以下insert为legal.
db.users.insert({"username" : "bob"})
> db.users.insert({"username" : "bob", "age" : 23})
> db.users.insert({"username" : "fred", "age" : 23})
稀疏索引sparse indexes
与关系型数据库的稀疏索引概念不同,稀疏索引就是索引只包含被索引字段的文档。任何一个稀疏的缺失某一个字段的文档将不会存储在索引中,之所以称之为稀疏索引就是说缺失字段的文档的值会丢失。(不在时,不被存入索引,那么如果存在,但为null,会存入索引吗?还需实验)
如果索引字段可能不存在,又要保证unique,就可以如下方式建立。
db.ensureIndex({"email" : 1}, {"unique" : true, "sparse" : true})
使用sparse indexes 可能会影响查询结果。
不使用索引时
> db.foo.find({"x" : {"$ne" : 2}})
{ "_id" : 0 }
{ "_id" : 1, "x" : 1 }
{ "_id" : 3, "x" : 3 }
但是你如果对“x”建立稀疏索引,
> db.foo.find({"x" : {"$ne" : 2}})
{ "_id" : 1, "x" : 1 }
{ "_id" : 3, "x" : 3 }
索引管理
所有关于数据库索引的信息都存在system.indexes集合里面。也可以运行db.collectionName.getIndexes() 来查看一个指定集合的索引信息。
索引名称默认为 keyname1_dir1_keyname2_dir2_..._keynameN_dirN ,keynameX为索引的皱键名, dirX 指索引的升降序方向 (1 or -1)。
也可以用如下命令指定index名称
> db.foo.ensureIndex({"a" : 1, "b" : 1, "c" : 1, ..., "z" : 1},
... {"name" : "alphabet"})
默认情况下,mongodb会尽快建立索引,阻塞所有读写操作,直到索引被建立完毕。你如果想保证对读写仍有响应,可以使用后台运行的参数来建索引。
相关推荐
在本文中,我们将深入探讨 MongoDB 数据库索引的基础知识、类型、创建方式、使用注意点等方面的内容。 索引基础 ---------- 为什么需要索引?索引可以显著地提高查询性能。例如,在没有索引的情况下,MongoDB 需要...
下面将详细阐述MongoDB的一些核心知识点。 1. **面向集合的文档存储**: MongoDB 使用文档作为数据存储的基本单元,这些文档是BSON(Binary JSON)格式,可以方便地存储JSON风格的数据。文档是键值对的集合,可以...
下面我们将详细讨论 MongoDB 索引的限制及其相关知识点。 1. **系统限制** - **额外开销**:每个索引都需要占用存储空间,并在插入、更新和删除操作中维护。如果集合主要进行写操作,过多的索引可能导致不必要的...
本篇资料主要涵盖了 MongoDB 的索引使用和查询分析,以下是对这些知识点的详细解释: 1. **explain操作**:`explain` 是 MongoDB 提供的一个命令,用于分析查询的执行计划。通过 `explain`,我们可以获取查询如何...
通过以上详细介绍,我们不仅了解了MongoDB的基本概念和技术细节,还深入探讨了其安装配置、操作管理、备份恢复、认证授权以及复制等方面的知识点,为运维人员和数据库管理员提供了全面的技术指南。
以下是关于MongoDB创建索引的一些详细知识点: 1. **创建索引的方法**: MongoDB 使用 `ensureIndex()` 方法来创建索引。尽管在较新的版本中,`createIndex()` 已经成为推荐的创建索引的方法,但`ensureIndex()` ...
### MongoDB知识点学习手册 #### 一、Mongodb简介 MongoDB 是一个开源的、面向文档存储的数据库系统,属于 NoSQL 数据库的一种。其名称来源于单词 "humongous"(巨大的),表明 MongoDB 设计用于处理大规模的数据...
本文将深入探讨在"JAVA核心知识点整理"中涉及的关键概念和技术。 一、Java基础 Java的基础知识包括语法、面向对象特性(封装、继承、多态)、异常处理、输入/输出流以及集合框架。了解基本类型、类、接口、包的概念...
下面是 MongoDB 的详细知识点: 1. 简介 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的 bson 格式,因此...
mongodb知识点总结, 涉及到mongodb的简单介绍 mongodb相关概念介绍 mongodb的安装(linux) mongodb的启动和连接 mongodb数据库和集合的操作,文档的增删改查相关操作 mongodb索引的建立和删除 mongodb的备份和恢复 ...
以下是一些关于MongoDB单机版的基本知识点: 1. **安装与配置**: - 下载:首先,你需要从MongoDB官方网站下载适合你操作系统(如Windows、Linux或macOS)的安装包。 - 安装:按照提供的指南进行安装,通常包括...
根据提供的信息,我们可以总结出以下关于 MongoDB 的关键知识点: ### MongoDB 概览 - **官方文档**:用户提及“mongodb 官方文档”,这表明文档是 MongoDB 的权威指南,覆盖了从入门到进阶的各种主题。 - **学习...
从提供的文件内容中,我们可以提取出以下关于MongoDB的知识点: 1. 关于NoSQL的知识点: NoSQL数据库是区别于传统关系型数据库的数据存储方式,它主要面对数据高并发性的实时读取与写入、海量数据存储和智能计算与...
**知识点2:MongoDB索引创建** 在MongoDB中,合理地使用索引能够极大地提高查询效率。根据给定的部分内容,我们可以学习到几种常见的索引创建方法: 1. **创建过期索引**: - `db.history.ensureIndex({"create_...
MongoDB in Action是一本专为开发者和数据库管理员深入理解MongoDB设计的书籍。源码是配合书中理论知识的实践部分,旨在帮助...无论是开发新项目还是优化现有系统,熟悉MongoDB的这些关键知识点都将大大提升工作效率。
下面是MongoDB中查询和索引的相关知识点: 一、find函数的使用 * find函数不带参数时,查询集合中所有文档 * find函数带条件参数时,查询符合条件的文档 * find函数可以指定返回的键 二、条件操作符的使用 * $...
### MongoDB 用户手册关键知识点概述 #### 一、文档与数据管理 - **Storing Data**:此章节重点介绍如何在 MongoDB 中存储数据。这包括基本的文档存储方式、最佳实践以及如何有效地组织数据来满足应用需求。 - **...