我有一个Azure表存储,其中包含来自数百个远程设备的微小遥测。数据由连接设备ID,位置ID,年份和年份的密钥分区。因此,举例来说,如果我想为任何给定的设备提取整整一个月的数据,我需要从30个分区中提取所有数据。
对于一个特定的计算,我只需要在小时的顶部和底部加上时间戳的记录,即分钟分别为0和30的时间。目前,为了做到这一点,我创建了一个任务数组来单独拉出每个记录并并行获取它们(一个月这是1440年 - 我知道每个记录的分区键和行键,所以我可以使用TableOperation.Retrieve< >(partitionKey,rowKey)方法。下面的代码说明了方法:
var tasks = new List<Task<TableResult>>();
foreach (var date in dates)
{
foreach (var timeOfDay in checkTimes)
{
var dateTimeLocal = date.Add(TimeSpan.Parse(timeOfDay));
var dateTimeUtc = Helper.ConvertLocalTimeToUtcTime(location.TimeZoneId, dateTimeLocal);
var partitionKey = location.RowKey + "_" + deviceGuid + "_" + dateTimeUtc.DayOfYear + "_" + dateTimeUtc.Year;
var rowKey = dateTimeUtc.ToString("yyyy-MM-ddTHH:mm:00");
var table = TableHelper.GetTable(Data.StorageString, "table");
var retrieveOperation = TableOperation.Retrieve<DataEntities.EnergyData>(partitionKey, rowKey);
tasks.Add(table.ExecuteAsync(retrieveOperation));
}
}
await Task.WhenAll(tasks.ToArray());
var demandData = tasks.Where(c => c.Result.Result != null).Select(c => (DataEntities.EnergyData)c.Result.Result).ToArray();
日期数组包含我想要聚合的每一天的午夜时间,而checkTimes是我每天对每天感兴趣的时间。
对于一个月的数据(约1440条记录),这种方法可能需要花费更长的时间,而不仅仅是拉动每个记录一个月,并在内存中过滤我感兴趣的记录 - 我期待它要快得多。
关于为什么这么慢运行的任何想法(例如,对于Table Storage来说,这是一个限制问题)吗?有更快更可靠的方法吗?我开始认为最好的方法就是将分钟为0或30的每一行的副本复制到另一个表中,以便我可以在一些较大的查询中检索我需要的内容。
答案 0 :(得分:0)
正如Query Entities所述:
针对Table服务的查询可能一次返回最多1,000个实体,并且最多可以执行5秒。如果结果集包含超过1,000个实体,如果查询未在五秒内完成,或者查询跨越分区边界,则响应包括包含一组延续令牌的自定义标头。继续令牌可用于构造对下一页数据的后续请求。
根据您的方案,您已指定partitionKey
和rowKey
来检索单个记录。根据我的理解,此时,您的客户端会针对表格服务发送1000多个请求,而对于Partition Range Scan或Row Range Scan,它只会发送多个请求。
我认为使用Point Queries时可能会导致网络延迟(使用等式谓词指定单个PartitionKey和RowKey)。您可以enable azure storage metrics用于表格存储,并通过Microsoft Azure Storage Explorer检查AverageE2ELatency
和AverageServerLatency
指标,如下所示:
有关表存储指标的更多详细信息,请参阅Transactions Table Schema。
关于为什么这么慢运行的任何想法(例如,对于Table Storage来说,这是一个限制问题)吗?有更快更可靠的方法吗?我开始认为最好的方法就是将分钟为0或30的每一行的副本复制到另一个表中,以便我可以在一些较大的查询中检索我需要的内容。
根据我的理解,您可以通过在一个月范围内指定RowKey(例如rowKey>="2016-06-01T00:00:00" and rowKey<="2016-06-30T23:59:59"
)来利用Row Range Scan来检索给定设备的记录,然后按照您的预期在内存中过滤