Performance Cosmos CreateDocumentQuery linq在何处条件下的性能
我有一个cosmos集合,大约有28000个文档,我在DocumentClient上使用CreateDocumentQuery,在类型为“T”的属性上使用where条件。在下面提到的不同类型的使用中,我在获得结果时得到了非常大的时间延迟差异 案例1:Performance Cosmos CreateDocumentQuery linq在何处条件下的性能,performance,linq,azure-cosmosdb,azure-cosmosdb-sqlapi,Performance,Linq,Azure Cosmosdb,Azure Cosmosdb Sqlapi,我有一个cosmos集合,大约有28000个文档,我在DocumentClient上使用CreateDocumentQuery,在类型为“T”的属性上使用where条件。在下面提到的不同类型的使用中,我在获得结果时得到了非常大的时间延迟差异 案例1: var docs2 = _documentClient.CreateDocumentQuery<HeartRateDayRecordIdentifierData>(collectionUri).Where(x =>
var docs2 =
_documentClient.CreateDocumentQuery<HeartRateDayRecordIdentifierData>(collectionUri).Where(x =>
x.SubjectDeviceInformation.StudyId == "TestStudy"
&& x.SubjectDeviceInformation.SiteId == "Site_._Street_23"
&& x.SubjectDeviceInformation.SubjectId == "Subject3"
&& x.SubjectDeviceInformation.DeviceId == "Device1"
&& x.DaySplit == "20181112").AsEnumerable().FirstOrDefault();
下面是用于反序列化文档的模型:
内部类HeartRateDayRecordIdentifierData
{
公共字符串id{get;set;}
public string AssemblyVersion { get; set; }
public string DataItemId { get; set; }
public string MessageType { get; set; }
public DateTime TimeStamp { get; set; }
public string DaySplit { get; set; }
public SubjectDeviceInformation SubjectDeviceInformation { get; set; }
}
internal class SubjectDeviceInformation
{
public string SubjectId { get; set; }
public string DeviceId { get; set; }
public string StudyId { get; set; }
public string SiteId { get; set; }
}
对我在这里做的任何错误都有任何建议。在这两种情况下,你都是在以非最佳方式做这件事 如果没有匹配项,则只需要first或null 但是,您正在通过调用
AsEnumerable().FirstOrDefault()
执行同步跨分区查询调用
此外,where子句应该是表达式,而不是Func
在这两种情况下,首先返回CosmosDB中的所有数据,然后LINQ执行内存过滤以返回数据
相反,您应该使用while(query.HasMoreResults)
和query.ExecuteNextAsync()
方法返回数据
以下是您的查询方式:
public async Task<HeartRateDayRecordIdentifierData> GetSomethingAsync()
{
var query =
_documentClient.CreateDocumentQuery<HeartRateDayRecordIdentifierData>(collectionUri).Where(x =>
x.SubjectDeviceInformation.StudyId == "TestStudy"
&& x.SubjectDeviceInformation.SiteId == "Site_._Street_23"
&& x.SubjectDeviceInformation.SubjectId == "Subject3"
&& x.SubjectDeviceInformation.DeviceId == "Device1"
&& x.DaySplit == "20181112").AsDocumentQuery();
while(query.HasMoreResults)
{
var results = await query.ExecuteNextAsync();
if(results.Any())
return results.First();
}
return null;
}
你可以自己选择你的出路。
免责声明,我是宇航员的创造者。感谢您的详细分析。从您的分析中得出以下几点:1.我不认为在前面使用where条件的.AsEnumerable().FirstOrDefault()
不会提取所有数据,因为当我尝试按下面的\u documentClient.CreateDocumentQuery(\u uri)。where(x=>x.SubjectDeviceInformation.StudyId==“TestStudy”和&x.SubjectDeviceInformation.SiteId==“Site.\u Street\u 23”和&x.SubjectDeviceInformation.SubjectId==“Subject3”和&x.SubjectDeviceInformation.DeviceId==“Device1”和&x.dayspilt==“20181112”)。ToString()
返回的sql查询与{“查询”:“从根目录中选择*,其中(((((根目录[\'SubjectDeviceInformation\\'][\'StudyId\'][\'TestStudy\”)和(根目录[\'SubjectDeviceInformation\'][\'SiteId\'][\'Site\'][\'U Street\'U 23\”)和(根目录[\'SubjectDeviceInformation\'][\'SubjectId\'][\']=“Subject3\”)和(根目录[\'SubjectDeviceInformation\\\\']['SubjectDeviceInformation\\\\'']]['DeviceId\\''''']=“Device1\”)”和根目录[\\\\”)”\“20181112\”))
这正是它需要做的\u documentClient.CreateDocumentQuery(\u uri).其中(x=>x.SubjectDeviceInformation.StudyId==“NOR580”&&x.SubjectDeviceInformation.SiteId==“Site.\u Street\u 23”&&x.SubjectDeviceInformation.SubjectId==“Subject3”&&x.SubjectDeviceInformation.DeviceId==“设备1”&&x.dayspilt==“20181112”).ToList()
这正是它所需要做的,因此它没有从cosmos返回整个文档并从本地进行过滤,我甚至使用fiddler验证了有效负载。然而,我做的最愚蠢的事情是将变量声明为Func
,而不是Expression
,我太傻了:(.在本例中,Func
查询为空,将整个文档列表绑定并在本地进行筛选。非常感谢您指出这一点。更改变量类型后,一切正常。(使用fiddler验证两种情况下的有效负载)
public string AssemblyVersion { get; set; }
public string DataItemId { get; set; }
public string MessageType { get; set; }
public DateTime TimeStamp { get; set; }
public string DaySplit { get; set; }
public SubjectDeviceInformation SubjectDeviceInformation { get; set; }
}
internal class SubjectDeviceInformation
{
public string SubjectId { get; set; }
public string DeviceId { get; set; }
public string StudyId { get; set; }
public string SiteId { get; set; }
}
public async Task<HeartRateDayRecordIdentifierData> GetSomethingAsync()
{
var query =
_documentClient.CreateDocumentQuery<HeartRateDayRecordIdentifierData>(collectionUri).Where(x =>
x.SubjectDeviceInformation.StudyId == "TestStudy"
&& x.SubjectDeviceInformation.SiteId == "Site_._Street_23"
&& x.SubjectDeviceInformation.SubjectId == "Subject3"
&& x.SubjectDeviceInformation.DeviceId == "Device1"
&& x.DaySplit == "20181112").AsDocumentQuery();
while(query.HasMoreResults)
{
var results = await query.ExecuteNextAsync();
if(results.Any())
return results.First();
}
return null;
}
public async Task<HeartRateDayRecordIdentifierData> GetSomethingAsync()
{
return await cosmosStore.Query().Where(x =>
x.SubjectDeviceInformation.StudyId == "TestStudy"
&& x.SubjectDeviceInformation.SiteId == "Site_._Street_23"
&& x.SubjectDeviceInformation.SubjectId == "Subject3"
&& x.SubjectDeviceInformation.DeviceId == "Device1"
&& x.DaySplit == "20181112").FirstOrDefaultAsync();
}