更新时间:2024-05-30 GMT+08:00

数据库性能

  • 业务禁止出现任何全表扫描的查询。
  • 执行查询时,只选择需要返回的字段,不需要的字段不要返回。从而减少网络和进程处理的负载,修改数据时,只修改变化需要修改的字段,不要整个对象直接存储全部修改。
  • 避免使用$not。GeminiDB Mongo并不会对缺失的数据进行索引,因此$not的查询条件将会要求在一个结果集中扫描所有记录。如果$not是唯一的查询条件,会对集合进行全表扫描。
  • 用$and时把匹配最少结果的条件放在最前面,用$or时把匹配最多结果的条件放在最前面。
  • 单个实例中,数据库的总的个数不要超过200个,总的集合个数不要超过500个。集合数量过多会导致内存压力变高,并且集合数量多会导致重启以及主备倒换性能变差,影响紧急情况下的高可用性能。
  • 业务上线前,一定要对数据库进行性能压测,评估业务峰值场景下,对数据库的负载情况。
  • 禁止同时执行大量并发事务,且长时间不提交。
  • 业务正式上线前, 所有的查询类别,都应该先执行查询计划检查查询性能。

    开发过程中,对集合的每一个操作都要通过执行explain()检查其执行计划。

    例如:

    db.T_DeviceData.find({"deviceId" : "ae4b5769-896f"}).explain();

    db.T_DeviceData.find({"deviceId" : "77557c2-31b4"}).explain("executionStats");

    对于查询而言,因为覆盖查询不需要读取文档,而是直接从索引中返回结果,这样的查询非常高效,所以尽可能使用索引覆盖查询。如果explain()的输出显示indexOnly字段为真,则说明这个查询就被一个索引覆盖。

    执行计划解析:

    • 看执行时间:executionStats.executionStages.executionTimeMillisEstimate和executionStats.executionStages.inputStage. executionTimeMillisEstimate时间越短越好。
      • executionStats.executionTimeMillis表示执行计划选择和执行的所有时间。
      • executionStats.executionStages.executionTimeMillisEstimate表示最优执行计划的执行完成时间。
      • executionStats.executionStages.inputStage. executionTimeMillisEstimate表示最优执行计划下的子阶段执行完成时间。
    • 看扫描条数(三个条目相同为最佳)
      • executionStats. nReturned表示匹配查询条件的文档数。
      • executionStats .totalKeysExamined表示索引扫描条目数。
      • executionStats .totalDocsExamined表示文档扫描条目数。
    • 看Stage状态(性能较好的Stage状态组合)
      • Fetch+IDHACK
      • Fetch+ixscan
      • Limit+(Fetch+ixscan)
      • PROJECTION+ixscan
      表1 状态说明

      状态名称

      描述

      COLLSCAN

      全表扫描

      SORT

      内存中进行排序

      IDHACK

      根据_id进行查询

      TEXT

      全文索引

      COUNTSCAN

      未用索引计数

      FETCH

      索引扫描

      LIMIT

      使用Limit限制返回数

      SUBPLA

      未用索引的$or查询阶段

      PROJECTION

      使用索引计数

      COUNT_SCAN

      使用索引计数