当前位置: 首页 > 知识库问答 >
问题:

在cosmos db中,通过id检索文档的速度很慢

卢永寿
2023-03-14

我有一个场景,我需要根据其id属性从azure cosmos db检索单个文档。唯一的问题是我不知道分区键,因此无法使用文档URI来访问它。

根据我的理解,编写一个简单的查询,如

SELECT * from c WHERE c.id = "id here"

这应该是一条路,但我遇到了这个查询的严重性能问题。大多数查询需要30到60秒才能完成,并且似乎消耗了大量的RU/s。当执行10个并发查询时,每个分区的最大RU/s高达30.000(每个分区配置10.00),导致节流和响应更慢。

该集合包括10个分区,每个分区大约有3 Mb,因此总共有30 Mb,大约有10万个文档。我的索引策略如下所示:

{
    "indexingMode": "lazy",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*",
            "indexes": [
                {
                    "kind": "Range",
                    "dataType": "Number",
                    "precision": -1
                },
                {
                    "kind": "Hash",
                    "dataType": "String",
                    "precision": 3
                }
            ]
        }
    ],
    "excludedPaths": []
}

一致性设置为< code > finally ,因为我并不关心读/写顺序。该集合有一定的写入压力,大约每分钟30次写入,每个文档的TTL为1年,但这似乎不会对RU/s产生可测量的影响。我只在查询文档时遇到这种问题。

有人遇到过类似的问题并且可以提供修复/缓解吗?我的查询或索引策略有问题吗?我不知道为什么我的查询会消耗这么多资源。

共有3个答案

仉成益
2023-03-14

宇宙的关键是重新思考分区的关键。我不知道您正在使用什么,但请让它非常可用。

最近,我在我的所有文档中添加了一个“表”属性,但是您可以很容易地将表名用作分区键!这实际上几乎就像有一堆SQL表在CosmosDB集合的布丁中浮动。

仲孙兴旺
2023-03-14

我的测试DB关于300k记录当我尝试选择ID只有这样

SELECT * FROM c where c.id = 'xxx'

这花了我很多时间和RU

但是当我尝试使用分区键时

SELECT * FROM c where c.id = 'xxx' AND c.partitionField = 'yyy'

它非常快

所以我认为你必须重建你的数据库,并考虑用哪个字段来分区

叶建柏
2023-03-14

我也有类似的问题。我的数据库是16 GB,有两个分区,每个分区有10,000 RU。

通过收集查询指标,我发现< code>query by id可能正在进行表扫描,而不是从索引中查找。

这是按id查询的指标:

SELECT * FROM c where c.id = 'id-here'
--Read 1 record in 1497.00 ms, 339173.109 RU
--QueryPreparationTime(ms): CompileTime = 2, LogicalBuildTime = 0, 
     PhysicalPlanBuildTime = 0, OptimizationTime = 0
--QueryEngineTime(ms): DocumentLoadTime = 1126, IndexLookupTime = 0, 
     RuntimeExecutionTimes = 356, WriteOutputTime = 0

请注意,时间主要花在文档加载时间IndexLookupTime=0上。

而按索引字段的查询速度非常快。

SELECT * FROM c WHERE c.indexedField = 'value'
--Read 4 records in 2.00 ms, 7.56 RU
--QueryPreparationTime(ms): CompileTime = 0, LogicalBuildTime = 0, 
       PhysicalPlanBuildTime = 0, OptimizationTime = 0
--QueryEngineTime(ms): DocumentLoadTime = 0, IndexLookupTime = 1, 
       RuntimeExecutionTimes = 0, WriteOutputTime = 0

与按 id 查询相反,这不会消耗文档加载时间,因为使用了索引,索引查找时间为 1 毫秒。

问题是< code>id应该是主键,并且在默认情况下应该被索引,但看起来却不是。你甚至不能为它添加自定义索引策略。

我目前正在登录Microsoft支持并等待澄清。

更新:

微软支持部门做出了回应,他们已经解决了这个问题。他们为集合添加了索引版本 2。不幸的是,它尚未从门户中获得,并且新创建的帐户/集合仍未使用新版本。你必须联系微软支持部门才能对你的帐户进行更改。

以下是索引版本2的集合的新结果,它有了巨大的改进。

SELECT * FROM c where c.id = 'uniqueValue'
-- Index Version 1: Request Charge: 344,940.79 RUs
-- Index Version 2: Request Charge: 3.31 RUs

SELECT * FROM c WHERE c.indexedField = 'value' AND c.id = 'uniqueValue'
-- Index Version 1: Request Charge: 150,666.22 RUs 
-- Index Version 2: Request Charge: 5.65 RUs

 类似资料:
  • 正如MS Support最近告诉我的那样,使用“GET”在RU的使用中比sql查询更有效。我想知道我是否可以(在azure.cosmospython包中或对REST API的自定义HTTP请求中)通过其唯一的“id”字段(我为其生成了GUID)获取文档,而无需SQL查询。 显示的每个示例都使用文档的链接/路径,该链接/路径是使用文档的“_rid”元数据构建的,而不是在创建文档时设置的“id”字段。

  • 我试图检索一个索引中的所有文档,但只得到_id字段。 基本上,我想检索我拥有的所有文档ID。 使用时: 我得到的命中包含:" _index "、" _type "、" _id "、" _score "、" _source ",这比我需要的要多得多。 编辑(回答):所以我的问题是我使用KOPF来运行查询,结果不准确(得到了_source等等…)!当使用curl时,我得到了正确的结果! 所以上面的查询

  • 我已经创建了一个azure函数,当一个新文档被添加到一个集合中时,它会被触发。 是否可以从该集合中选择特定文档,然后查询所选文档中的数据? 例如,在所谓的募集服装,我有一个文件,有一个ID: 12345Tops.我想查询ID为:12345Tops的文档中找到的数据。 或者检索集合中的第一个文档,然后查询第一个选定文档 我看过带有http触发器的azure函数:https://docs.micros

  • 如果我有一个数据,其结构类似于集合中的单个文档: 有没有办法通过id“childid”搜索嵌入的文档?因为mongo没有索引嵌入文档的_id字段(如果我在这里错了,请纠正我),因为这个查询不起作用:db。收集查找({u id:“childid”}); 另外,请告知我是否有任何其他文档数据库适用于这种树结构的检索数据,其中要求: 查询子级而不必发出联接 查找树中的任何节点的速度与查找根节点的速度一样

  • 我有一个带有单个endpoint的API,它从CosmosDB集合中检索文档。endpoint在常见场景下工作良好。然而,当我在API上执行压力测试,以测量它在重负载下如何响应时,我在站点上经历了中断(站点开始用502 - bad网关响应请求)。 在Application Insights上搜索时,我注意到在执行句子以从CosmosDB集合中检索文档时引发了OutOfMemory异常。我用来读取文

  • 正如我从“云火数据模型”指南中得到的,“每个文档都由一个名称标识。”是否可以通过该文档标识符(即名称或ID)查询集合? 例如,集合“Things”中的文档具有IDs、1、2等。: 是否可以查询 ID 小于 100 的文档?