首页 > 解决方案 > Cosmos DB 加快读取速度

问题描述

我正在尝试从 Cosmos DB 中检索大约 10,000 个项目。保存数据大约需要 30 秒,但检索数据大约需要 50 秒。每条记录的大小约为 6KB。

string sqlQueryText = $"SELECT * FROM c WHERE c.FK in (1,2,3,4,5,6,7,...N)";
QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText);

FeedIterator<MyObject> myFeedIterator= Container.GetItemQueryIterator<MyObject>(queryDefinition, null, new QueryRequestOptions
{
    PartitionKey = pk,
    MaxConcurrency = 20,
    MaxItemCount = 2000              
});

List<MyObject> myObjects = new List<MyObject>();

while(myFeedIterator.HasMoreResults)
{
    Microsoft.Azure.Cosmos.FeedResponse<MyObject> feedResponses = await myFeedIterator.ReadNextAsync();

    foreach(MyObject feedResponse in feedResponses)
    {
        myObjects.Add(feedResponse);
    }
}

有谁知道我可以加快这个查询的方法吗?

谢谢你,特拉维斯佩特里

标签: c#azure-cosmosdb

解决方案


由于您的项目大小如此之大,因此此查询可能总是会受到长时间运行的影响。10K * 6K 是 60MB 的数据。每次获取的页面大小为 4MB,因此将进行 15 次往返以完全耗尽该查询。MaxConcurrency 最大值只会是您拥有的物理分区数,因此您可以将其设置为 -1。最大项目数也将受页面大小的限制,因此 4MB/6K 将在每批中为您提供约 660 个项目。

至于性能,我会考虑以下几点:

重新评估你的数据模型,看看你是否真的需要 6KB 的记录。如果您进行大量读取但仅对数据子集进行读取,则应将文档分解为两个或多个文档。如果您还进行大量插入,尤其是在进行大量更新时尤其如此,因为每次更新,即使只是很小的更新,都会对整个 6K 数据进行替换。

您可以做的另一件最好的事情是重塑您的数据,使其不是跨分区的。如果您非常频繁地运行此查询或需要非常快的性能,则尤其如此。如果您编写的数据要求您拥有当前的分区键以优化写入但还运行大量查询,则应考虑使用更改源并保留两份数据副本,一份用于写入,另一份用于使用回答查询。


推荐阅读