Profiing

MongoDB提供了名为Database Profier的profiing能力,它记录关于数据库操作的五种粒度信息。profier 能够记录所有事件的信息,或者仅记录持续时间超过可配置阈值(缺省值为100ms)的那些事件。探查数据存储在一个有上限的集合中,在那里可以方便地搜索相关事件。它可能比解析日志fies更容易查询这个集合。

MongoDB Ops Manager和Cloud Manager(稍后在指南中讨论)可用于在识别慢速查询时可视化验证程序的输出。Visual Query Profier为操作团队和DBA提供了一种快速方便的方法来分析指定查询或查询系列。Visual Query Profier(如图3所示)显示了查询和写入延迟如何随时间变化——使得识别具有公共访问模式和特征的较慢查询以及识别任何延迟峰值变得简单。在Ops Manager UI中单击一次即可激活验证器,然后验证器将合并并显示单个屏幕中每个节点的度量。

mongodb oplog在哪找 mongodb ops manager_字段

 

图3:MongoDB Ops Manager中的可视化查询分析

主索引和次级索引

为所有文档创建_id属性上的唯一索引。如果插入文档时没有指定_id,MongoDB将自动创建该字段,并分配一个惟一值。所有用户定义的索引都是次级索引。MongoDB包括对许多类型的次级索引的支持,这些索引可以在文档中的任何字段上声明,包括数组和子文档中的字段。索引选项包括:

  • 复合索引
  • 地理位置索引
  • 全文索引
  • 唯一索引
  • 数组索引
  • TTL(过期)索引
  • 稀疏索引
  • 部分索引
  • 哈希索引
  • 不同语言的排序索引(MongoDB 3.4中新增的)

 

可以从MongoDB体系结构指南了解更多关于这些索引的信息

索引创建选项

在MongoDB中,索引和数据是同步更新的,这样确保了对索引的查询永远不会返回过期或删除的数据。作为方案设计过程的一部分,应该使用适当的索引。默认情况下,在MongoDB中创建索引是一个阻塞操作。由于索引的创建可能耗费时间和资源,MongoDB提供了在副本集的主和从上创建新的索引的后台操作选项。当启用后台选项时,创建索引的总时间将比在前台创建索引时要长,但是仍然可以在创建索引时查询数据库。

一种常见的做法是在前台中构建索引,首先在从服务器上构建索引,然后再在降级的主服务器上构建索引。Ops Manager和Cloud Manager使这个过程自动化。

此外,可以在后台同时构建多个索引。请参阅“在副本集上构建索引”文档,以了解有关创建索引和进行维护的更多注意事项。

 

使用MongoDB WiredTiger存储引擎管理索引

所有存储引擎都完全支持MongoDB丰富的索引功能。在使用WiredTiger存储引擎时,还可以利用以下一些额外的优化:

 

  • 默认情况下,WiredTiger使用前置压缩来减少持久存储和RAM中的索引占用。这使得管理员能够将更多的工作专注于管理频繁访问的文档。一般情况下大约有50%的压缩率,但是鼓励用户通过测试自己的工作负载来评估他们期望的实际比率。
  • 管理员可以将索引放在它们自己的独立存储卷上,从而允许更快的磁盘分页和更低的争用。

 

索引限制

与任何数据库一样,索引消耗磁盘空间和内存,因此应该只在必要时使用。索引会影响更新性能。更新必须首先定位要更改的数据,因此索引在这方面会有帮助,但是索引维护本身有开销,并且这项工作会降低更新性能。

在部署MongoDB时,应该留意几个关于索引限制:

  • 一个集合不能有超过64个索引
  • 索引条目不能超过1024个字节
  • 索引的名称不能超过125个字符(包括它的命名空间)。
  • 没有索引的数据的内存排序限制为32MB。这个操作非常耗费CPU,内存排序表明应该创建索引来优化这些查询。

关于索引的常见错误

以下提示可能有助于避免关于索引的一些常见错误:

  • 使用复合索引而不要索引交集:在基于多个条件进行查询时获得最佳性能,复合索引通常是更好的选择。
  • 复合索引:复合索引是基于字段的顺序来定义的。 如果一个复合索引由姓、名、城市来定义的,那么指定了姓,或者指定了姓和名的查询就会用上这个复合索引。但是基于城市的查询,就用不上该复合索引了。
  • 低选择性索引:索引应该从根本上减少要从中选择的一组可能的文档。
  • 正则表达式:索引是按值排序的,因此前置通配符无效,可能导致完整的索引扫描。如果表达式中有足够的区分大小写的前置字符,则结尾通配符可能是有效的。
  • 不等于:不等式查询对于索引可能是不合适的。与大多数数据库系统一样,MongoDB不等条件,或者否定条件可能需要扫描所有文档。如果不等于是唯一的条件并且不是选择性的(例如,查询订单表,其中99%的订单已经完成,以识别那些尚未完成的订单),则需要扫描所有记录。
  • 消除不必要的索引: 索引是资源密集型的:即使它们消耗RAM,并且随着文件更新,也必须维护它们关联的索引,从而引起额外的磁盘I/O开销。为了理解正在使用的现有索引的有效性,可以使用$indexStats聚合阶段来确定使用每个索引的频率。如果没有使用索引,那么删除它们将减少存储并加速写入。索引使用 还可以通过MongoDB  Compass GUI查看。
  • 部分索引:  如果只需要在给定索引中包括文档的子集,那么可以通过指定更合适的表达式使索引部分化。例如,如果用户ID文件上的索引仅用于查询打开的订单,则可以将其设置为以正在进行的订单状态为条件。通过这种方式,部分索引提高了查询性能,同时最小化了开销。