笔记
Posted YuYunTan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了笔记相关的知识,希望对你有一定的参考价值。
MongoDB实战第二版笔记(9)第八章笔记
1、正确设置索引,MongoDB可以高效使用其硬件,并且快速服务查询。而错误索引导致查询减速、写减速、恶化硬件设备使用。【高效使用MongoDB为何要理解索引?】
2、索引分简单索引和复合索引。
3、索引规则:
(1)索引可大大减少要处理的文档数量。没有适当索引,唯一满足条件的查询方式则是扫描全部文档,直到找到满足条件的查询。这通常指的是查询整个集合。
(2)唯一的单键索引将会用来处理查询【 $or
操作符查询是例外】。对于包含多个键的查询,包含这些键的复合索引是最好的解决方案。
(3)如果有一个复合索引a-b,那么a上的索引是多余的,b上的不多于。
(4)复合索引的键值顺序很重要。
4、单键索引。每个索引入口对应文档索引里的单个值。默认的索引在_id字段。
5、复合索引。2.6版本后可以一个查询使用多个索引,但最好还是只使用一个索引。复合索引是每个入口由多个键值组成的单个索引。
6、MongoDB绝大部分索引使用B-树结构。B树结构的特点:一、方便各种查询,包括精确匹配、范围条件查询、排序、前缀匹配、索引查询。二、在添加和删除键值之后都会保持平衡。
7、唯一索引,会确保在所有文档中的一致性,要创建指定unique参数即可。
db.users.createIndex(username:1,unique:true)
如果在集合上需要唯一索引,最好在插入数据之前创建索引。提前创建索引,可以确保从开始建立约束。当在包含数据的集合上创建唯一索引可能会失败,因为集合中可能存在重复数据。当重复键值存在,则索引创建失败。
8、要在已有集合上创建唯一索引,可以重复尝试创建唯一索引,用错误信息删除重复键值。如果数据部重要,可以用dropDups参数来让MongoDB删除重复键值,但该参数在3.0版本已删除,可以创建新集合,在新集合上创建,然后从旧集合复制到新集合(确保复制过程中忽略错误或手动处理重复键值)。
9、稀疏索引,只有包含某些索引键值的文档才会出现,要创建,则指定sparse:true。
10、使用稀疏索引的情况:
- 想在集合里不是每个文档中都出现的字段上建立唯一索引
- 集合中大佬文档不包含所有键值
11、多键索引。思想是多个索引入口或键值,引用同一个文档。智能使用该索引对MongoDB scheme设计十分重要。
12、哈希索引。通过hashed参数创建。
db.recipes.createIndex(recipe_name:'hashed')
因为所言值是最初参数的哈希值,所以有如下限制:
- 等值查询相似,不支持范围查询
- 不支持多键哈希
- 浮点数在哈希之前转换为整数
既然有这些限制为什么使用哈希? 因为哈希索引上的入口是均匀分布的。当有键值数据不均匀分布时,哈希函数可以创建均匀性。哈希索引可以跨片或跨机存储。
13、地理空间索引。功能是查询某个地点附近的文档,基于经纬度来存储每个文档。
14、创建索引是createIndex()方法,原理创建一个带有新索引的文档并把它存储到专门的system.indexes集合。删除则使用deleteIndexes。
use green
db.runCommand(deleteIndexes:"users",index:"zip")
15、使用getIndexes()方法检查索引规范。也可以使用dropIndex方法删除索引。
use green
db.users.dropIndex("zip")
16、索引构建分两步,第一步对构建索引的值进行排序。排序过的值插入B-树里效率更高,排序进度使用有序文档占全部文档的比例表示。第二步,排序后的值插入索引中,构建索引花费时间使用插入system.indexes的时间来指示。
17、可以使用currentOp()方法来检查索引构建进度。
18、如果在生产情况下无法停止数据库访问,可以指定在后台构建索引。只需要声明索引时指定background:true参数就可以【构建索引会占用写锁,但允许其他用户读/写数据库,后台索引有时会影响性能】。
db.values.createIndex(open:1,close:1,background:true)
19、离线索引。由于后台构建索引可能对生成服务器造成无法接受的压力,就需要离线构建索引。这需要离线复制一个新的服务器节点,在此服务器上创建索引,并允许此服务器复制主服务器数据。一旦更新完毕,就把此服务器当主服务器,然后采用第二台离线服务器构建其所有的版本。
该策略假设复制oplog日志足够大,以避免脱机服务器在索引构建中丢失数据。
20、索引碎片最大问题是实际空间远远大于数据所需空间,导致使用更多的内存空间,则考虑重建索引。
使用reIndex命令重新创建索引。
db.values.reIndex()
21、查询优化是找出慢速查询,发现问题并解决问题的过程。
22、MongoDB日志器会打印索引查询时间超过100ms的操作,可以作为分析慢速查询的第一个入口。
23、可用下面命令简单的实现查询工作
grep -E '[0-9]+ms' mongod.log
在启动MongoDB可以设置-slowms参数记录超过多少ms的操作。
24、FROFILER通常被禁用,如果找不到比内置分析器更好的工具则使用该工具分析慢速查询。
use stocks
db.setProfilingLevel(2)
首先选择要监控的数据库,分析范围是某个数据库。分析级别为2.则会告诉分析器记录每个读/写操作。为1,记录慢速操作耗时超时100ms的。为0,只记录耗时超时的操作,传递毫秒为第二个参数。
db.setProfillingLevel(1,50)
25、监控结果保存到特殊的盖子集合,system.profile里,存储在执行setProfilingLevel命令的数据库中。
盖子集合,固定大小,一旦达到最大数量,新文档取代旧文档。
system.profile集合分配128KB,确保监控分析数据不耗费太多资源。
26、查询所有耗时超过150ms的操作
db.system.profile.find(millis:$gt:150)
27、监控策略:
- 使用监控分析器良好方式是使用粗略设置和向下工作模式启动它【先确保没有超过100ms的,再继续75ms的】。
- 启用监控分析器后,若要监控所有应用程序的操作,则意味测试所有应用程序的读取和写入操作
- 要彻底分析问题,则这些读/写操作应在真实条件下执行,当数据大小、查询负载、硬件与生产环境一样时,查询效果最好。
28、最简单的情况,缺少所有,不恰当的索引低于期望查询,可以用explain命令找出原因。
29、查询优化器使用的简单规则:
- 避免scanAndOrder。如果查询包含排序,则尝试使用索引排序
- 使用有用索引约束满足所有字段—尝试为查询选择器中的字段使用索引
- 如果查询包含范围或者排序,则选择最后一个key使用的索引来帮助处理范围和排序。
如果对任意的索引这些条件都满足,则所有索引就会是最佳的而且可以使用。如果多个索引都最佳,则任意选择其中一个。如果可以为查询构建最佳索引,就可以大大简化优化器的工作,因此请尽量做到。
30、优化器在下列事件发生后会自动过期计划:
- 集合中写入了100次
- 集合新建或者删除了所有
- 如果查询计划的查询做了比期望更多的工作。衡量“更多的工作”用的是nscanned的值超过了缓存的nscanned的值至少是10。
31、单键索引的应用环境:
- 精确匹配。无论是返回0个,1个还是多个结果都使用索引。
- 排序:在索引字段上排序
- 范围查询。可能在同一个字段上使用或不使用排序
32、复合索引的可能应用场景:
- 精确匹配。在第一个键上精确匹配。第一和第二个键,或第一,第二和第三个键使用指定的顺序
- 范围匹配。在任意集合最左边键(包括none)上的精确匹配,并且使用限制范围或者排序。
- 覆盖索引。是索引的特殊使用。当需要的数据都驻留在所有里,索引可以说覆盖了查询,又称为索引查询。因为这些查询不需要访问具体的索引文档。
以上是关于笔记的主要内容,如果未能解决你的问题,请参考以下文章