C# Azure表存储查询的性能较慢

C# Azure表存储查询的性能较慢,c#,azure,task-parallel-library,azure-table-storage,C#,Azure,Task Parallel Library,Azure Table Storage,我正在对Azure表存储运行一系列结构良好的查询,据我所知,这些查询应该会返回亚秒级。事实上,如果我手动运行它们,比如说,从VisualStudio中的Azure工具,它们确实会立即返回。但当我在生产中运行它们时,它们有时需要20-30秒才能返回 以下是我调用ATS的C代码: public async Task<IList<T>> FindAsync(string filter, int maxRecords = int.MaxValue, IList<string

我正在对Azure表存储运行一系列结构良好的查询,据我所知,这些查询应该会返回亚秒级。事实上,如果我手动运行它们,比如说,从VisualStudio中的Azure工具,它们确实会立即返回。但当我在生产中运行它们时,它们有时需要20-30秒才能返回

以下是我调用ATS的C代码:

public async Task<IList<T>> FindAsync(string filter, int maxRecords = int.MaxValue, IList<string> columns = null)
{
    var returnList = new List<T>();
    try
    {
        Interlocked.Increment(ref _outstandingRequests);
        var query = new TableQuery<T>().Where(filter);
        if (columns != null && columns.Any())
        {
            query = query.Select(columns);
        }
        TableQuerySegment<T> querySegment = null;
        var sw = new Stopwatch();
        sw.Start();
        while (returnList.Count < maxRecords && (querySegment == null || querySegment.ContinuationToken != null))
        {
            try
            {
                await 3.RetriesAsync(async x =>
                {
                    querySegment = await
                        Table.ExecuteQuerySegmentedAsync(query,
                            querySegment != null ? querySegment.ContinuationToken : null);
                });
                returnList.AddRange(querySegment);
            }
            catch (Exception ex)
            {
                _logger.Error("Error executing ATS query; table:{0}; filter:{1}; error:{2}",
                    typeof(T).GetFriendlyTypeName(), filter, ex.CompleteMessage());
                throw;
            }
        }
        sw.Stop();
        if (sw.ElapsedMilliseconds > 10000)
        {
            var stat = new RepoOperationStats(filter, sw, returnList.Count, _outstandingRequests);
            _logger.Warn("Long-running {0} query: secs:{1:0.0}, rc:{2}, or:{3}, fi:{4}",
                typeof(T).GetFriendlyTypeName(), stat.Milliseconds / 1000d, stat.ResultCount, stat.OutstandingRequests, stat.Filter);
        }
    }
    finally
    {
        Interlocked.Decrement(ref _outstandingRequests);
    }
    return returnList;
}
下面是一个存储在表中的实体示例:

一切都相当简单。但在我的日志中,我看到重复出现的错误如下:

通过cookie查询在OrganizationEventSummary上长时间运行: 秒:33.3, rc:0, 或:94, fi:PartitionKey eq'4306.www detail mercury mars skywatching tips.html get'和RowKey ge'2015.02.05.00000000-0000-0000-00000000000000'和RowKey le'2015.02.07.00000000-0000-0000-00000000'

换句话说,返回零行需要33秒。请注意,它正好命中一个分区,并且应该能够对该分区内的行索引执行简单的查找。事实上,同一查询在其他上下文中会立即返回

我遇到过什么节流机制吗?我应该注意到,我并行调用这些查询,因此在任何给定的时间点,从十几个到100个以上的查询都可能是未完成的。但似乎a我的客户和b ATS都应该能够处理这一级别的负载


关于如何解决这个问题,有什么建议吗?

azure stoage日志怎么说?这通常很有启发性。缓慢的正常原因是跨分区搜索和/或表扫描,即表的线性搜索。我查看了存储日志,没有看到任何非常有趣的内容。延迟数据似乎在20-30毫秒之内,其他任何东西看起来都不正常。我同意分区和/或表扫描是性能问题的典型来源,但在本例中,我将查询分解为每个查询只命中一个分区,并且具有合理的行键约束。当您说延迟数字是20-30毫秒时,哪个延迟?端到端,还是服务器?如果E2E延迟非常低,那么问题不在对存储器的调用中,而是在代码的其他地方。您是否已在while循环中添加了跟踪语句,以确保使用预期参数和预期次数调用代码?还考虑启用客户端跟踪存储客户端库——我指的是$MeTimeCurrPrimaClient表中的AuvaGe2Eeltusient和Apple AdvesteRealFrimeStudio。它们都在30-40毫秒左右。值得一提的是,在进一步调查中,我发现只有大约.1%的查询运行得这么慢。我仍然不知道是什么原因造成的,但到目前为止,我已经用更好的缓存解决了这个问题,这意味着更少的对ATS的查询,也意味着更少的慢查询。