在 c# 中 CosmosDB DocumentDB 和 SqlAPI 性能低下
Slow performance with CosmosDB DocumentDB and SqlAPI in c#
我需要 运行 查询 returns 来自 CosmosDB
集合的大约 30,000 项。要在代码 I post 中执行此查询,执行时间大约为 2 分半钟,即使将吞吐量提高 40 倍,您也没有得到实质性的改进,时间减少到 1 分钟。
public static async Task<IEnumerable<T>> GetItemsCompact(string whereclause)
{
string collectionToUse;
SqlQuerySpec sqlQuerySpec = new SqlQuerySpec();
if (typeof(T).ToString().IndexOf("Telemetry") != -1)
{
DocumentDBRepository<CosmosDBTelemetry>.Initialize();
collectionToUse = AppSettings.Collection;
sqlQuerySpec.QueryText = "SELECT c.messageUID as messageUID, ";
sqlQuerySpec.QueryText += "c.deviceId as deviceId, ";
sqlQuerySpec.QueryText += "udf.UDF_VIn(c.VIn) as VIn, ";
sqlQuerySpec.QueryText += "udf.UDF_AIn(c.AIn) as AIn, ";
sqlQuerySpec.QueryText += "udf.UDF_W(c.W) as W, ";
sqlQuerySpec.QueryText += "udf.UDF_Var(c.Var) as Var, ";
sqlQuerySpec.QueryText += "c.EventProcessedUtcTime as EventProcessedUtcTime ";
sqlQuerySpec.QueryText += "from Telemetry c ";
sqlQuerySpec.QueryText += whereclause;
}
else
{
DocumentDBRepository<CosmosDBEvents>.Initialize();
collectionToUse = AppSettings.Collection2;
sqlQuerySpec.QueryText = "select doc.uid as uid, ";
sqlQuerySpec.QueryText += "doc.deviceId as deviceId, ";
sqlQuerySpec.QueryText += "doc.eventId as eventId, ";
sqlQuerySpec.QueryText += "doc.ts as ts, ";
sqlQuerySpec.QueryText += "doc.startTS as startTS, ";
sqlQuerySpec.QueryText += "doc.endTS as endTS, ";
sqlQuerySpec.QueryText += "doc.no as no, ";
sqlQuerySpec.QueryText += "doc.params as params, ";
sqlQuerySpec.QueryText += "doc.tags as tags ";
sqlQuerySpec.QueryText += "from Events doc ";
sqlQuerySpec.QueryText += whereclause;
}
FeedOptions opt = new FeedOptions
{
EnableCrossPartitionQuery = true,
MaxItemCount = -1
};
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(AppSettings.Database, collectionToUse), sqlQuerySpec,opt).AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
有人可以帮助我提高性能吗?
这完全在意料之中。 Cosmos DB 不应该那样使用。您正在执行跨分区查询。理想情况下,这永远不应该发生,至少不会在您的应用程序的正常逻辑中发生。最重要的是,您将 MaxItemCount
设置为 -1
。这意味着您希望 Cosmos return 单个页面中的所有内容。不建议这样做,因为 Cosmos DB 仅 return 分页结果,而这是最好的时候。您可以将页面大小更改为 100-250
之类的值,但这仍然不会显着提高性能。 Cosmos DB 不适合在这种情况下执行。
我需要 运行 查询 returns 来自 CosmosDB
集合的大约 30,000 项。要在代码 I post 中执行此查询,执行时间大约为 2 分半钟,即使将吞吐量提高 40 倍,您也没有得到实质性的改进,时间减少到 1 分钟。
public static async Task<IEnumerable<T>> GetItemsCompact(string whereclause)
{
string collectionToUse;
SqlQuerySpec sqlQuerySpec = new SqlQuerySpec();
if (typeof(T).ToString().IndexOf("Telemetry") != -1)
{
DocumentDBRepository<CosmosDBTelemetry>.Initialize();
collectionToUse = AppSettings.Collection;
sqlQuerySpec.QueryText = "SELECT c.messageUID as messageUID, ";
sqlQuerySpec.QueryText += "c.deviceId as deviceId, ";
sqlQuerySpec.QueryText += "udf.UDF_VIn(c.VIn) as VIn, ";
sqlQuerySpec.QueryText += "udf.UDF_AIn(c.AIn) as AIn, ";
sqlQuerySpec.QueryText += "udf.UDF_W(c.W) as W, ";
sqlQuerySpec.QueryText += "udf.UDF_Var(c.Var) as Var, ";
sqlQuerySpec.QueryText += "c.EventProcessedUtcTime as EventProcessedUtcTime ";
sqlQuerySpec.QueryText += "from Telemetry c ";
sqlQuerySpec.QueryText += whereclause;
}
else
{
DocumentDBRepository<CosmosDBEvents>.Initialize();
collectionToUse = AppSettings.Collection2;
sqlQuerySpec.QueryText = "select doc.uid as uid, ";
sqlQuerySpec.QueryText += "doc.deviceId as deviceId, ";
sqlQuerySpec.QueryText += "doc.eventId as eventId, ";
sqlQuerySpec.QueryText += "doc.ts as ts, ";
sqlQuerySpec.QueryText += "doc.startTS as startTS, ";
sqlQuerySpec.QueryText += "doc.endTS as endTS, ";
sqlQuerySpec.QueryText += "doc.no as no, ";
sqlQuerySpec.QueryText += "doc.params as params, ";
sqlQuerySpec.QueryText += "doc.tags as tags ";
sqlQuerySpec.QueryText += "from Events doc ";
sqlQuerySpec.QueryText += whereclause;
}
FeedOptions opt = new FeedOptions
{
EnableCrossPartitionQuery = true,
MaxItemCount = -1
};
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(AppSettings.Database, collectionToUse), sqlQuerySpec,opt).AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
有人可以帮助我提高性能吗?
这完全在意料之中。 Cosmos DB 不应该那样使用。您正在执行跨分区查询。理想情况下,这永远不应该发生,至少不会在您的应用程序的正常逻辑中发生。最重要的是,您将 MaxItemCount
设置为 -1
。这意味着您希望 Cosmos return 单个页面中的所有内容。不建议这样做,因为 Cosmos DB 仅 return 分页结果,而这是最好的时候。您可以将页面大小更改为 100-250
之类的值,但这仍然不会显着提高性能。 Cosmos DB 不适合在这种情况下执行。