Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.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
C# 如何在azure表存储中使用partitionkey加速查询_C#_Azure_Azure Table Storage_Azure Virtual Network_Azure Tablequery - Fatal编程技术网

C# 如何在azure表存储中使用partitionkey加速查询

C# 如何在azure表存储中使用partitionkey加速查询,c#,azure,azure-table-storage,azure-virtual-network,azure-tablequery,C#,Azure,Azure Table Storage,Azure Virtual Network,Azure Tablequery,如何提高此查询的速度? var over1000Results = table.ExecuteQueryAsync(treanslationsQuery).Result.Cast<Translation>(); return over1000Results.Where(x => x.expireAt > DateTime.Now) .Where(x => x.effectiveAt <

如何提高此查询的速度?

  var over1000Results = table.ExecuteQueryAsync(treanslationsQuery).Result.Cast<Translation>();
        return over1000Results.Where(x => x.expireAt > DateTime.Now)
                           .Where(x => x.effectiveAt < DateTime.Now);
在执行以下查询的
1-2分钟内,我们大约有100名消费者。这些运行中的每一次都代表消费函数的一次运行

        TableQuery<T> treanslationsQuery = new TableQuery<T>()
         .Where(
          TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, sourceDestinationPartitionKey)
           , TableOperators.Or,
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, anySourceDestinationPartitionKey)
          )
         );
TableQuery-treanslationquery=newtablequery()
.在哪里(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,sourceDestinationPartitionKey)
,表格操作员。或,
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,anySourceDestinationPartitionKey)
)
);
此查询将产生大约5000个结果。

完整代码:

    public static async Task<IEnumerable<T>> ExecuteQueryAsync<T>(this CloudTable table, TableQuery<T> query) where T : ITableEntity, new()
    {
        var items = new List<T>();
        TableContinuationToken token = null;

        do
        {
            TableQuerySegment<T> seg = await table.ExecuteQuerySegmentedAsync(query, token);
            token = seg.ContinuationToken;
            items.AddRange(seg);
        } while (token != null);

        return items;
    }

    public static IEnumerable<Translation> Get<T>(string sourceParty, string destinationParty, string wildcardSourceParty, string tableName) where T : ITableEntity, new()
    {
        var acc = CloudStorageAccount.Parse(Environment.GetEnvironmentVariable("conn"));
        var tableClient = acc.CreateCloudTableClient();
        var table = tableClient.GetTableReference(Environment.GetEnvironmentVariable("TableCache"));
        var sourceDestinationPartitionKey = $"{sourceParty.ToLowerTrim()}-{destinationParty.ToLowerTrim()}";
        var anySourceDestinationPartitionKey = $"{wildcardSourceParty}-{destinationParty.ToLowerTrim()}";

        TableQuery<T> treanslationsQuery = new TableQuery<T>()
         .Where(
          TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, sourceDestinationPartitionKey)
           , TableOperators.Or,
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, anySourceDestinationPartitionKey)
          )
         );

        var over1000Results = table.ExecuteQueryAsync(treanslationsQuery).Result.Cast<Translation>();
        return over1000Results.Where(x => x.expireAt > DateTime.Now)
                           .Where(x => x.effectiveAt < DateTime.Now);
    }
公共静态异步任务ExecuteQueryAsync(此CloudTable表,TableQuery查询),其中T:ITableEntity,new()
{
var items=新列表();
TableContinuationToken=空;
做
{
TableQuerySegment seg=wait table.ExecuteQuerySegmentedAsync(查询,令牌);
令牌=seg.ContinuationToken;
项目。添加范围(seg);
}while(令牌!=null);
退货项目;
}
公共静态IEnumerable Get(string sourceParty、string destinationParty、string wildcardSourceParty、string tableName),其中T:ITableEntity,new()
{
var acc=CloudStorageAccount.Parse(Environment.GetEnvironmentVariable(“conn”));
var tableClient=acc.CreateCloudTableClient();
var table=tableClient.GetTableReference(Environment.GetEnvironmentVariable(“TableCache”));
var sourceDestinationPartitionKey=$“{sourceParty.ToLowerTrim()}-{destinationParty.ToLowerTrim()}”;
var anySourceDestinationPartitionKey=$“{wildcardSourceParty}-{destinationParty.ToLowerTrim()}”;
TableQuery-TreanslationQuery=新建TableQuery()
.在哪里(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,sourceDestinationPartitionKey)
,表格操作员。或,
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,anySourceDestinationPartitionKey)
)
);
var over1000Results=table.ExecuteQueryAsync(treanslationquery.Result.Cast();
返回超过1000个结果。其中(x=>x.expireAt>DateTime.Now)
其中(x=>x.effectiveAt
在这些执行过程中,当有100个消费者时,如您所见,请求将群集并形成峰值:

在这些峰值期间,请求通常需要超过1分钟:

如何提高此查询的速度?
var over1000Results=table.ExecuteQueryAsync(treanslationquery.Result.Cast();
  var over1000Results = table.ExecuteQueryAsync(treanslationsQuery).Result.Cast<Translation>();
        return over1000Results.Where(x => x.expireAt > DateTime.Now)
                           .Where(x => x.effectiveAt < DateTime.Now);
返回超过1000个结果。其中(x=>x.expireAt>DateTime.Now) 其中(x=>x.effectiveAt
这里有一个问题,您正在运行查询,然后使用这些“where”从内存中过滤它。在查询运行之前将筛选器移动到,这将非常有帮助


其次,您必须提供从数据库检索的行数限制

不幸的是,下面的查询引入了一个完整表扫描:

    TableQuery<T> treanslationsQuery = new TableQuery<T>()
     .Where(
      TableQuery.CombineFilters(
        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, sourceDestinationPartitionKey)
       , TableOperators.Or,
        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, anySourceDestinationPartitionKey)
      )
     );
TableQuery-treanslationquery=newtablequery()
.在哪里(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,sourceDestinationPartitionKey)
,表格操作员。或,
TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,anySourceDestinationPartitionKey)
)
);

您应该将其拆分为两个分区键筛选器并分别查询它们,这将成为两个分区扫描
,执行效率更高。

您可以考虑三件事:

1。首先,去掉对查询结果执行的
Where
子句。最好在查询中尽可能多地包含子句(如果您的表中有任何索引也包含子句,则更好)。现在,您可以按如下方式更改查询:

var translationsQuery = new TableQuery<T>()
.Where(TableQuery.CombineFilters(
TableQuery.CombineFilters(
    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, sourceDestinationPartitionKey),
    TableOperators.Or,
    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, anySourceDestinationPartitionKey)
    ),
TableOperators.And,
TableQuery.CombineFilters(
    TableQuery.GenerateFilterConditionForDate("affectiveAt", QueryComparisons.LessThan, DateTime.Now),
    TableOperators.And,
    TableQuery.GenerateFilterConditionForDate("expireAt", QueryComparisons.GreaterThan, DateTime.Now))
));
然后您可以在
Get
方法中调用它:

return table.ExecuteQueryAsync(translationsQuery).Cast<Translation>();
返回table.ExecuteQueryAsync(translationsQuery.Cast();
正如您所看到的,方法本身不是异步的(您应该更改它的名称)并且是并行的。ForEach与传入异步方法不兼容。这就是为什么我使用了
ExecuteQuerySegmented
。但是,为了使其性能更高并利用异步方法的所有优点,您可以将上述
ForEach
循环替换为中的
ActionBlock
方法或中的
ParallelForEachAsync
扩展方法

2。执行独立的并行查询,然后合并结果是一个不错的选择,即使其性能提高最多10%。这使您有时间找到性能最佳的查询。但是,永远不要忘记在其中包含所有约束,并测试两种方法,以确定哪种方法更适合您的问题。

3。我不确定这是不是一个好建议,但去做吧,看看结果如何。如中所述:

表服务强制服务器超时,如下所示:

  • 查询操作:在超时时间间隔内,可能会执行以下查询: 最多五秒钟。如果查询未在 在五秒钟的时间间隔内,响应包括延续标记 用于检索后续请求中的剩余项。参见查询 有关详细信息,请参阅超时和分页

  • 插入、更新和删除