首页 > 解决方案 > CosmosDB,很长的索引,也是分区键

问题描述

我们正在存储一个文件夹树,项目数量很大,所以我们在父文件夹上创建了一个分区。

当我们发出诸如

SELECT * FROM root WHERE root.parentPath = "\\server\share\shortpath" AND root.isFile 

RU 非常低,性能非常好。

但是,当我们有一条很长的路时,例如

SELECT * FROM root WHERE root.parentPath = "\\server\share\a very\long\path\longer\than\this" AND root.isFile

RU 上升到 5000 并且性能受到影响。

parentPathall由于查询在过滤器中包含此字段,因此可以很好地用作分区键。

如果我在查询中添加另一个子句,它也会变得非常快,例如,如果我做类似的事情and root.name = 'filename'

这几乎就像是根据从它派生的散列扫描整个分区。

查询返回 NO DATA

这很好,因为有人在给定节点下寻找子文件夹,一旦深入,它就会变得非常慢。

查询指标

x-ms-documentdb-query-metrics: 

totalExecutionTimeInMs=1807.61;
queryCompileTimeInMs=0.08;
queryLogicalPlanBuildTimeInMs=0.04;
queryPhysicalPlanBuildTimeInMs=0.06;
queryOptimizationTimeInMs=0.01;
VMExecutionTimeInMs=1807.11;
indexLookupTimeInMs=0.65;
documentLoadTimeInMs=1247.08;
systemFunctionExecuteTimeInMs=0.00;
userFunctionExecuteTimeInMs=0.00;
retrievedDocumentCount=72554;
retrievedDocumentSize=59561577;
outputDocumentCount=0;
outputDocumentSize=49;
writeOutputTimeInMs=0.00;
indexUtilizationRatio=0.00

从字符串

x-ms-documentdb-query-metrics: totalExecutionTimeInMs=1807.61;queryCompileTimeInMs=0.08;queryLogicalPlanBuildTimeInMs=0.04;queryPhysicalPlanBuildTimeInMs=0.06;queryOptimizationTimeInMs=0.01;VMExecutionTimeInMs=1807.11;indexLookupTimeInMs=0.65;documentLoadTimeInMs=1247.08;systemFunctionExecuteTimeInMs=0.00;userFunctionExecuteTimeInMs=0.00;retrievedDocumentCount=72554;retrievedDocumentSize=59561577;outputDocumentCount=0;outputDocumentSize=49;writeOutputTimeInMs=0.00;indexUtilizationRatio=0.00

标签: azure-cosmosdb

解决方案


这是因为 Indexing v1 中的路径长度限制。

我们在新的索引布局中将路径长度限制增加到了更大的值,因此将集合迁移到这个新布局将解决问题并提供许多性能优势。

默认情况下,我们为新集合推出了新的索引布局。如果您可以重新创建当前集合并将现有数据迁移到那里,那就太好了。否则,另一种方法是触发迁移过程以将现有集合移动到新的索引布局。可以使用以下 C# 方法来执行此操作:

static async Task UpgradeCollectionToIndexV2Async(

        DocumentClient client,

        string databaseId,

        string collectionId)

    {

        DocumentCollection collection = (await client.ReadDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseId, collectionId))).Resource;

        collection.SetPropertyValue("IndexVersion", 2);

        ResourceResponse<DocumentCollection> replacedCollection = await client.ReplaceDocumentCollectionAsync(collection);

        Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Upgraded indexing version for database {0}, collection {1} to v2", databaseId, collectionId));

    }

迁移可能需要几个小时才能完成,具体取决于集合中的数据量。问题一旦完成就应该得到解决。

(这是从我们必须解决此问题的电子邮件对话中复制粘贴的)


推荐阅读