使用 spring 数据在 mongo 中查询执行时间的问题

问题描述 投票:0回答:0

我对查找查询的响应时间太长有疑问。
这很奇怪,因为如果我自己运行查询(例如通过 dataGrip / Intellij 驱动程序),响应时间约为 500-700 毫秒,而当它由使用 spring data mongo 的服务执行时,响应时间为 33000毫秒到 45000 毫秒
不仅时间不同——而且使用

.explain(“executionStats”)
更具体地验证查询——
keysExamined
docsExamined
的数量。

这是查询:

db.fooCollection.find({
    "$or": [{
      "$and": [{
        "params": {
          "$elemMatch": {
            "name": "manufacturer",
            "val": "FooManufacturer"
          }
        }
      }, {
        "params": {
          "$elemMatch": {
            "name": "articleId",
            "val": "FOO-FOO-ARTICLE-ID-FOO"
          }
        }
      }]
    }, {
      "$and": [{
        "params": {
          "$elemMatch": {
            "name": "brand",
            "val": "FooManufacturer"
          }
        }
      }, {
        "params": {
          "$elemMatch": {
            "name": "articleId",
            "val": "FOO-FOO-ARTICLE-ID-FOO"
          }
        }
      }]
    }]
  }).collation({
    locale: 'en',
    strength: 1,
    alternate: "shifted",
    maxVariable: "punct"
  })
  .explain("executionStats")

这是手动查询运行的

executionStats

{
  "executionSuccess": true,
  "nReturned": new NumberInt("1"),
  "executionTimeMillis": new NumberInt("2"),
  "totalKeysExamined": new NumberInt("1"),
  "totalDocsExamined": new NumberInt("1"),
  "executionStages": {
    "stage": "SUBPLAN",
    "nReturned": new NumberInt("1"),
    "executionTimeMillisEstimate": new NumberInt("2"),
    "works": new NumberInt("2"),
    "advanced": new NumberInt("1"),
    "needTime": new NumberInt("0"),
    "needYield": new NumberInt("0"),
    "saveState": new NumberInt("0"),
    "restoreState": new NumberInt("0"),
    "isEOF": new NumberInt("1"),
    "inputStage": {
      "stage": "FETCH",
      "filter": {
        "$or": [{
          "$and": [{
            "params": {
              "$elemMatch": {
                "$and": [{
                  "name": {
                    "$eq": "articleId"
                  }
                }, {
                  "val": {
                    "$eq": "FOO-FOO-ARTICLE-ID-FOO"
                  }
                }]
              }
            }
          }, {
            "params": {
              "$elemMatch": {
                "$and": [{
                  "name": {
                    "$eq": "brand"
                  }
                }, {
                  "val": {
                    "$eq": "FooManufacturer"
                  }
                }]
              }
            }
          }]
        }, {
          "$and": [{
            "params": {
              "$elemMatch": {
                "$and": [{
                  "name": {
                    "$eq": "articleId"
                  }
                }, {
                  "val": {
                    "$eq": "FOO-FOO-ARTICLE-ID-FOO"
                  }
                }]
              }
            }
          }, {
            "params": {
              "$elemMatch": {
                "$and": [{
                  "name": {
                    "$eq": "manufacturer"
                  }
                }, {
                  "val": {
                    "$eq": "FooManufacturer"
                  }
                }]
              }
            }
          }]
        }]
      },
      "nReturned": new NumberInt("1"),
      "executionTimeMillisEstimate": new NumberInt("0"),
      "works": new NumberInt("2"),
      "advanced": new NumberInt("1"),
      "needTime": new NumberInt("0"),
      "needYield": new NumberInt("0"),
      "saveState": new NumberInt("0"),
      "restoreState": new NumberInt("0"),
      "isEOF": new NumberInt("1"),
      "docsExamined": new NumberInt("1"),
      "alreadyHasObj": new NumberInt("0"),
      "inputStage": {
        "stage": "IXSCAN",
        "nReturned": new NumberInt("1"),
        "executionTimeMillisEstimate": new NumberInt("0"),
        "works": new NumberInt("2"),
        "advanced": new NumberInt("1"),
        "needTime": new NumberInt("0"),
        "needYield": new NumberInt("0"),
        "saveState": new NumberInt("0"),
        "restoreState": new NumberInt("0"),
        "isEOF": new NumberInt("1"),
        "keyPattern": {
          "params.name": new NumberInt("1"),
          "params.val": new NumberInt("1")
        },
        "indexName": "params.name_1_params.val_1",
        "collation": {
          "locale": "en",
          "caseLevel": false,
          "caseFirst": "off",
          "strength": new NumberInt("1"),
          "numericOrdering": false,
          "alternate": "shifted",
          "maxVariable": "punct",
          "normalization": false,
          "backwards": false,
          "version": "57.1"
        },
        "isMultiKey": true,
        "multiKeyPaths": {
          "params.name": ["params"],
          "params.val": ["params"]
        },
        "isUnique": false,
        "isSparse": false,
        "isPartial": false,
        "indexVersion": new NumberInt("2"),
        "direction": "forward",
        "indexBounds": {
          "params.name": ["[CollationKey(0xCOLLECTION_KEY), CollationKey(0xCOLLECTION_KEY)]"],
          "params.val": ["[CollationKey(0xCOLLECTION_KEY_2), CollationKey(0xCOLLECTION_KEY_2)]"]
        },
        "keysExamined": new NumberInt("1"),
        "seeks": new NumberInt("1"),
        "dupsTested": new NumberInt("1"),
        "dupsDropped": new NumberInt("0")
      }
    }
  }
}

这很有趣-来自服务日志(相同的查询,相同的数据库,执行中使用的相同索引)

 "planSummary": 
   "IXSCAN { params.name: 1, params.val: 1 }, IXSCAN { params.name: 1, params.val: 1 }",
   "keysExamined": 87182,
   "docsExamined": 87182,
   "cursorExhausted": true,
   "numYields": 484,
   "nreturned": 1,

相同查询的结果在每种情况下都是不同的(服务与手动运行)。我尝试在 dataGrip 中使用较旧版本的 mongo 驱动程序,因为我认为它可能在服务中已经过时,这就是为什么需要这么长时间才能收到答案 - 但没有。依然是手工制作精准快速

这是代码中的方法:

private suspend fun findByParams(parameters: Set < Map < ParamName, ParamValue >> ): CloseableIterator < ProductDocument > {
    val collation = Collation.of("en").strength(1).alternate("shifted").maxVariable("punct")
    val query = Query().collation(collation)
    val criterias = parameters.map {
        set - > set.map {
            Criteria.where("parameters").elemMatch(Criteria.where("name").iseEqualTo(it.key.name).and("value").isEqualTo(it.value.value))
        }
    }
    query.addCriteria(Criteria().orOperator(criterias.mapNotNull {
        Criteria().andOperator(it)
    }))
    return withContext(Dispatchers.IO) {
        mongoTemplate.stream(query, ProductDocument::class.java)
    }
}
spring mongodb kotlin mongodb-query spring-data-mongodb
© www.soinside.com 2019 - 2024. All rights reserved.