Lud*_*212 6 c# linq azure azure-cosmosdb
我在查询 CosmosDB 特定文档时定期执行 LINQ 谓词。然而,今天我的 CosmosDB 中填满了 10 万多个文档。表演非常缓慢。由于 Azure 门户中的 SQL 查询明显更快,因此我尝试使用 SqlQuerySpec。瞧\xc3\xa1!它的工作速度快得多。
\n\n谁能告诉我在 CosmosDB 中使用 Linq 谓词时到底发生了什么以及为什么它会减慢我的查询速度?
\n\n下面的代码在我的获取文档的方法中使用。\n注意:在本例中,id 是分区键。
\n\n var collectionUri = UriFactory.CreateDocumentCollectionUri(CDBdatabase, CDBcollection);\n\n var sqlStatement = new SqlQuerySpec\n {\n QueryText = "SELECT * FROM c where c.id = @id",\n Parameters = new SqlParameterCollection()\n {\n new SqlParameter("@id", consumerId),\n },\n };\n\n IDocumentQuery<T> query = documentClient.CreateDocumentQuery<T>(\n collectionUri,\n sqlStatement,\n .AsDocumentQuery();\n\n List<ConsumerDetails> results = new List<ConsumerDetails>();\n while (query.HasMoreResults)\n {\n results.AddRange(await query.ExecuteNextAsync<ConsumerDetails>());\n }\n\n return results.FirstOrDefault();\n
Run Code Online (Sandbox Code Playgroud)\n\n相对而言,较慢的代码:
\n\n return documentClient.CreateDocumentQuery<ConsumerDetails>(\n collectionUri,\n .Where(f => f.Id == consumerId).AsEnumerable().FirstOrDefault();\n
Run Code Online (Sandbox Code Playgroud)\n
答案在于您查询的方式。
您发布的两个代码段不相同。
为了使它们相同,第二个必须如下所示:
var collectionUri = UriFactory.CreateDocumentCollectionUri(CDBdatabase, CDBcollection);
var query = documentClient.CreateDocumentQuery<ConsumerDetails>(
collectionUri)
.Where(f => f.Id == consumerId)
.AsDocumentQuery();
List<ConsumerDetails> results = new List<ConsumerDetails>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<ConsumerDetails>());
}
return results.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您将针对 CosmosDB 执行 SQL。然而,在 LINQ 情况下,LINQ 翻译器将启动将表达式转换为 SQL 查询。
同样在 SQL 示例中,由于您直接指向小写字母id
(即 CosmosDB id
),它也是分区键,CosmosDB 将识别这一点并将查询从跨分区查询限制为特定分区查询,从而使其更快、更高效。更便宜。(.Where(f => f.Id == consumerId)
大写Id
)一旦通过 LINQ 提供程序,就会被转换为SELECT * FROM c where c.Id = consumerId
除非有JsonAttribute("id")
修饰Id
属性。这意味着您需要PartitionKey
在FeedOptions
查询中提供值。
归档时间: |
|
查看次数: |
1977 次 |
最近记录: |