RowKey上带有范围过滤器的慢Azure表查询

时间:2014-03-24 20:58:59

标签: azure azure-table-storage

我最近从Azure SDK 1升级到SDK 2,并转换了以下代码:

public IEnumerable<AnonymousSessionEntity> GetAnonymousSessions(Guid visitorId, Guid customerId, int connectionId, MergeOption mergeOption = MergeOption.AppendOnly)
{
    try
    {
        var partitionKey = AzureUtil.CombineToKey(customerId, connectionId);

        _tableStorageServiceContext.MergeOption = mergeOption;
        _tableStorageServiceContext.ResolveType = (unused) => typeof(AnonymousSessionEntity);

        var query = from s in _tableStorageServiceContext.CreateQuery<AnonymousSessionEntity>(TableStorageServiceContext.AnonymousSessionEntityName)
                         .Where(s => s.PartitionKey == partitionKey && s.RowKey.CompareTo(AzureUtil.GetRowKeyTimeLimit(90)) <= 0 && s.VisitorId == visitorId)
                    select s;

        CloudTableQuery<AnonymousSessionEntity> cloudTableQuery = query.AsTableServiceQuery<AnonymousSessionEntity>();
        IEnumerable<AnonymousSessionEntity> anonymousSessions = cloudTableQuery.Execute();

        return anonymousSessions;
    }
    catch (DataServiceQueryException e)
    {
        if (e.Response.StatusCode == (int)HttpStatusCode.NotFound) return null;
        else throw;
    }
}

进入以下内容:

public IEnumerable<AnonymousSessionEntity> GetAnonymousSessions(Guid visitorId, Guid customerId, int connectionId)
{
    var partitionKey = AzureUtil.CombineToKey(customerId, connectionId);
    var pkFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey);
    var rkFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, AzureUtil.GetRowKeyTimeLimit(90));
    var visitorIdFilter = TableQuery.GenerateFilterConditionForGuid("VisitorId", QueryComparisons.Equal, visitorId);
    var combinedFilter = string.Format("({0}) {1} ({2}) {3} ({4})", pkFilter, TableOperators.And, rkFilter, TableOperators.And, visitorIdFilter);

    var table = GetCloudTable(TableStorageDataSource.AnonymousSessionEntityName);
    var rangeQuery = new TableQuery<AnonymousSessionEntity>().Where(combinedFilter);

    var result = table.ExecuteQuery<AnonymousSessionEntity>(rangeQuery);
    return result;
}

正如您所看到的,我在partitionKey以及RowKey和自定义字段(称为“VisitorId”)上都有一个过滤器。此查询在SDK 1中运行良好,但新版本非常慢。事实上,它是如此之慢,以至于让我相信Azure会进行全表扫描(我在超过一分钟后停止计数)。我在这个表中有几百万行,所以我绝对不得不避免表扫描。

出于测试目的,我删除了v2查询中“VisitorId”字段的过滤器,它执行速度非常快:大概2-3秒。

有没有办法使用以下标准构建快速查询:

  1. PartitionKey上的完全匹配
  2. RowKey上的范围过滤器
  3. 自定义字段上的完全匹配

0 个答案:

没有答案