如何从具有多个PK的Azure表存储中获取许多表实体?

时间:2012-11-15 14:24:40

标签: azure azure-table-storage

我有一堆主键 - 成千上万,我想检索它们的关联表实体。所有行键都是空字符串。我知道这样做的最好方法是逐个查询异步。它似乎很快,但理想情况下我想在一个事务中将几个实体组合在一起。使用新的Storage Client,我有以下代码失败:

var sample = GetSampleIds(); //10000 pks

var account = GetStorageAccount();
var tableClient = account.CreateCloudTableClient();
var table = tableClient.GetTableReference("myTable");

//I'm trying to get first and second pk in a single request.
var keyA = sample[0];
var keyB = sample[1];

var filterA = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, keyA);
var filterB = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, keyB));

//filterAB = "(PartitionKey eq 'keyA') or (PartitionKey eq 'keyB')"
var filterAB = TableQuery.CombineFilters(filterA, TableOperators.Or, filterB);
var query = new TableQuery<TweetEntity>().Where(filterAB);

//Does something weird. I thought it might be fetching a range at one point.
//Whatever it does it doesn't return. Expected the following line to get an array of 2 items.
table.ExecuteQuery(query).ToArray()

// replacing filterAB in query with either filterA or filterB works as expected

示例总是显示CombineFilters在PK上工作,然后是RK,但这对我没用。我假设这是不可能的。

问题

是否可以通过PK将实体捆绑在一起?我知道最大过滤器长度为15,但是当您获取10,000个项目时,即使是2也是一个潜在的改进。另外,手册在哪里?无法在任何地方找到适当的文档例如,用于CombineFilters的MSDN是一个基本shell,包含了智能感知提供的更少信息。

2 个答案:

答案 0 :(得分:3)

tl; dr:听起来你需要重新考虑你的分区策略。当您通常需要查询或处理许多时,唯一的非顺序ID不是好的PK。更多:

分区键并不是真正的“主要”键。它们被认为是您希望使用的分组,密切相关的数据集。您可以按ID,日期等进行分组.PK用于扩展系统 - 理论上,每个PK可以有1个分区服务器处理您的数据。

对于你的问题:做你正在做的事情你不会有很好的表现。事实上,OR查询是非优化的,需要全表扫描(坏)。所以,不要做PK =“foo”或PK =“bar”,你真的应该做2个查询(并行),因为这会让你获得更好的性能。

回到核心问题,如果您使用特定实体的唯一标识符并将其描述为PK,那么这也意味着您无法在多个实体上工作。为了处理权限,您确实需要一个公共分区键。你能想到一个描述你的实体的更好的吗?日期/时间有效吗?其他一些常见的属性?那些往往是好的分区钥匙。您可以做的唯一其他事情是所谓的分区范围 - 您的查询往往在分区键上。一个例子是日期时间分区键。您可以使用文件刻度来描述您的分区,最后将序列数据滴答作为PK。然后,您的查询可以使用&gt;和&lt;查询以指定范围(无OR)。这些可以更优化,但你仍然可能获得大量的延续令牌。

答案 1 :(得分:0)

正如dunnry在回答中提到的,这种方法的问题在于OR查询速度非常慢。我没有存储客户端就让我的问题得以解决(此时,我不确定它有什么问题,让我们说这可能是一个错误),但是如果没有OR查询而单独获得2个实体就会变得多(!)比使用OR查询获得它们更快。