查询Azure表中最新项目的最快方法?

时间:2011-09-07 21:04:25

标签: azure azure-table-storage

我有一个Azure表,客户发布消息,单个表中可能有数百万条消息。我想找到最快的方式来获取最近10分钟内发布的消息(这是我刷新网页的频率)。由于只对分区键编制索引,因此我使用了日期&消息作为分区键发布的时间,例如字符串作为ISO8601日期格式,如“2009-06-15T13:45:30.0900000”

伪代码示例:

var message = "Hello word!";
var messagePartitionKey = DateTime.Now.ToString("o");
var messageEntity = new MessageEntity(messagePartitionKey, message);
dataSource.Insert(messageEntity);

,然后查询过去10分钟内发布的消息,如下所示(未经测试的伪代码):

// Get the date and time 10 minutes ago
var tenMinutesAgo = DateTime.Now.Subtract(new TimeSpan(0, 10, 0)).ToString("o");

// Query for the latest messages
var latestMessages = (from t in
   context.Messages
   where t.PartitionKey.CompareTo(tenMinutesAgo) <= 0
   select t
   )

但指数会好转吗?或者它会导致全表扫描?有人有更好的想法吗?我知道每个表项都有一个时间戳,但它没有编入索引,所以它对我来说太慢了。

4 个答案:

答案 0 :(得分:5)

我认为你有正确的基本想法。您设计的查询应该尽可能高效。但是我可以提供一些改进。

使用DateTime.Now而不是Date.UtcNow。根据我的理解实例设置为使用Utc时间作为他们的基础,但这只是确保你将苹果与苹果进行比较,并且你可以可靠地将时间转换回你想要的任何时区显示它们。

不是将时间存储为.ToString("o")而是将时间转换为刻度并存储,最终会减少格式化问题(有时候你会得到最终的时区规范,有时候不会)。此外,如果您总是希望看到从最近到最旧排序的这些消息,您可以从最大刻度数中减去刻度数,例如

var messagePartitionKey = (DateTime.MaxValue.Ticks - _contactDate.Ticks).ToString("d19");

指定行键也是一个好主意。虽然两个消息极不可能在完全相同的时间发布,但这并非不可能。如果您没有明显的行键,则只需将其设置为Guid。

答案 1 :(得分:4)

Table的主键是PartitionKey和RowKey(形成聚簇索引)的组合。

在你的情况下,只需使用RowKey而不是ParitionKey(为此提供一个常量值)。

您还可以按照诊断方法,例如每隔十分钟创建一个新的分区键。但这种方法主要用于诸如Archieving / Purging等的要求,

答案 2 :(得分:3)

我建议做类似于Diagnostics API与WADPerformanceCountersTable一样的操作。 PartitionKey将多个时间戳分组到一个项目中。即:它将所有时间戳舍入到最接近的几分钟(比如,最近的5分钟)。这样,您就没有有限数量的分区键,但仍然能够对它们进行远程查询。

因此,例如,您可以拥有一个映射到每个时间戳的PartitionKey,该时间戳四舍五入为00:00,00:05,00:10,00:15等等,然后转换为Ticks

答案 3 :(得分:0)

  • 根据我的理解,使用完全相等的分区键&#34; =&#34;将比使用&#34;&lt;&#34;或者&#34;大于&#34;&gt;。
  • 如果我们能够为您的条件获得分区键和行键的唯一组合,请务必付出更多努力。
  • 还要确保您执行的分区键值的唯一组合较少,以避免更多分区。