Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Cosmos CreateDocumentQuery linq在何处条件下的性能_Performance_Linq_Azure Cosmosdb_Azure Cosmosdb Sqlapi - Fatal编程技术网

Performance Cosmos CreateDocumentQuery linq在何处条件下的性能

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 =>

我有一个cosmos集合,大约有28000个文档,我在DocumentClient上使用CreateDocumentQuery,在类型为“T”的属性上使用where条件。在下面提到的不同类型的使用中,我在获得结果时得到了非常大的时间延迟差异

案例1:

    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();
}