`

MongoDB索引知识点的整理

阅读更多

 

链接地址: 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数据库索引介绍.pptx

    在本文中,我们将深入探讨 MongoDB 数据库索引的基础知识、类型、创建方式、使用注意点等方面的内容。 索引基础 ---------- 为什么需要索引?索引可以显著地提高查询性能。例如,在没有索引的情况下,MongoDB 需要...

    MongoDB知识点整理

    下面将详细阐述MongoDB的一些核心知识点。 1. **面向集合的文档存储**: MongoDB 使用文档作为数据存储的基本单元,这些文档是BSON(Binary JSON)格式,可以方便地存储JSON风格的数据。文档是键值对的集合,可以...

    MongoDB索引限制.pdf

    下面我们将详细讨论 MongoDB 索引的限制及其相关知识点。 1. **系统限制** - **额外开销**:每个索引都需要占用存储空间,并在插入、更新和删除操作中维护。如果集合主要进行写操作,过多的索引可能导致不必要的...

    MongoDB索引与查询.pdf

    本篇资料主要涵盖了 MongoDB 的索引使用和查询分析,以下是对这些知识点的详细解释: 1. **explain操作**:`explain` 是 MongoDB 提供的一个命令,用于分析查询的执行计划。通过 `explain`,我们可以获取查询如何...

    mongodb搭建,shell操作,索引,副本集

    通过以上详细介绍,我们不仅了解了MongoDB的基本概念和技术细节,还深入探讨了其安装配置、操作管理、备份恢复、认证授权以及复制等方面的知识点,为运维人员和数据库管理员提供了全面的技术指南。

    MongoDB索引的创建docx.pdf

    以下是关于MongoDB创建索引的一些详细知识点: 1. **创建索引的方法**: MongoDB 使用 `ensureIndex()` 方法来创建索引。尽管在较新的版本中,`createIndex()` 已经成为推荐的创建索引的方法,但`ensureIndex()` ...

    MongoDB知识点学习手册

    ### MongoDB知识点学习手册 #### 一、Mongodb简介 MongoDB 是一个开源的、面向文档存储的数据库系统,属于 NoSQL 数据库的一种。其名称来源于单词 "humongous"(巨大的),表明 MongoDB 设计用于处理大规模的数据...

    JAVA核心知识点整理

    本文将深入探讨在"JAVA核心知识点整理"中涉及的关键概念和技术。 一、Java基础 Java的基础知识包括语法、面向对象特性(封装、继承、多态)、异常处理、输入/输出流以及集合框架。了解基本类型、类、接口、包的概念...

    mongoDB笔记整理

    下面是 MongoDB 的详细知识点: 1. 简介 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的 bson 格式,因此...

    mongoDB总结大全

    mongodb知识点总结, 涉及到mongodb的简单介绍 mongodb相关概念介绍 mongodb的安装(linux) mongodb的启动和连接 mongodb数据库和集合的操作,文档的增删改查相关操作 mongodb索引的建立和删除 mongodb的备份和恢复 ...

    mongodb_单机基本知识点.zip

    以下是一些关于MongoDB单机版的基本知识点: 1. **安装与配置**: - 下载:首先,你需要从MongoDB官方网站下载适合你操作系统(如Windows、Linux或macOS)的安装包。 - 安装:按照提供的指南进行安装,通常包括...

    mongodb pdf

    根据提供的信息,我们可以总结出以下关于 MongoDB 的关键知识点: ### MongoDB 概览 - **官方文档**:用户提及“mongodb 官方文档”,这表明文档是 MongoDB 的权威指南,覆盖了从入门到进阶的各种主题。 - **学习...

    MongoDB简介与实践.pdf

    从提供的文件内容中,我们可以提取出以下关于MongoDB的知识点: 1. 关于NoSQL的知识点: NoSQL数据库是区别于传统关系型数据库的数据存储方式,它主要面对数据高并发性的实时读取与写入、海量数据存储和智能计算与...

    mongodb相关操作.txt

    **知识点2:MongoDB索引创建** 在MongoDB中,合理地使用索引能够极大地提高查询效率。根据给定的部分内容,我们可以学习到几种常见的索引创建方法: 1. **创建过期索引**: - `db.history.ensureIndex({"create_...

    MongoDB in action 源码

    MongoDB in Action是一本专为开发者和数据库管理员深入理解MongoDB设计的书籍。源码是配合书中理论知识的实践部分,旨在帮助...无论是开发新项目还是优化现有系统,熟悉MongoDB的这些关键知识点都将大大提升工作效率。

    nosql-实验八 在MongoDB中执行查询与创建索引.docx

    下面是MongoDB中查询和索引的相关知识点: 一、find函数的使用 * find函数不带参数时,查询集合中所有文档 * find函数带条件参数时,查询符合条件的文档 * find函数可以指定返回的键 二、条件操作符的使用 * $...

    mongodb-docs-2011-01-29_mongodb最新用户手册

    ### MongoDB 用户手册关键知识点概述 #### 一、文档与数据管理 - **Storing Data**:此章节重点介绍如何在 MongoDB 中存储数据。这包括基本的文档存储方式、最佳实践以及如何有效地组织数据来满足应用需求。 - **...

Global site tag (gtag.js) - Google Analytics