Azure Table 存储 API returns 0 个带有延续令牌的结果

Azure Table Storage API returns 0 results with Continuation Token

我们正在使用 .net Azure 存储客户端库从服务器检索数据。但是当我们尝试检索数据时,结果只有 0 个带有延续标记的项目。当我们用这个继续标记获取下一页时,我们再次得到相同的结果。然而,当我们使用像这样获取的第 4 个延续令牌时,我们得到了 15 个项目的正确结果。(所有请求的项目计数都是 15)。仅当我们尝试应用过滤条件时才会观察到此问题。用于获取结果的代码如下

    var tableReference = _tableClient.GetTableReference(tableName);
                var query = new TableQuery();
                query.Where("'DeviceId' eq '99'"); // DeviceId is of type Int32
                query.TakeCount = 15;

    var resultsQuery = tableReference.ExecuteQuerySegmented(query, token);
                var nextToken = resultsQuery.ContinuationToken;
                var results = resultsQuery.ToList();

这是预期的行为。来自 Query Timeout and Pagination:

A query against the Table service may return a maximum of 1,000 items at one time and may execute for a maximum of five seconds. If the result set contains more than 1,000 items, if the query did not complete within five seconds, or if the query crosses the partition boundary, the response includes headers which provide the developer with continuation tokens to use in order to resume the query at the next item in the result set. Continuation token headers may be returned for a Query Tables operation or a Query Entities operation.

我注意到您没有在查询中使用 PartitionKey。这将导致完整的 table 扫描。建议在您的查询中始终使用 PartitionKey(可能还有 RowKey)以避免完整的 table 扫描。我强烈建议阅读 Azure Storage Table Design Guide: Designing Scalable and Performant Tables 以充分利用 Azure Tables。

更新:解释 "If the query crosses the partition boundary"

让我用一个例子来说明我对分区边界的理解。假设您的 table 中有 100 万行均匀分布在 10 个分区中(假设您的 PartitionKey 为 001、002、003...010)。现在我们知道 Azure Tables 中的数据是按 PartitionKey 组织的,然后按 RowKey 组织在一个分区中。由于在您的查询中您没有指定 PartitionKey,Table 服务从第一个分区(即 PartitionKey == 001)开始并尝试在那里找到匹配的数据。如果它在那个分区中没有找到任何数据,它不知道数据是否在另一个分区中,所以它不会去下一个分区,而是简单地 returns 返回一个继续令牌并将它留给客户端使用 API 来决定他们是要使用相同的参数 + 继续标记继续搜索,还是修改他们的搜索以重新开始。