【问题标题】:Query azure table by collection of row keys通过行键集合查询天蓝色表
【发布时间】:2012-05-28 12:33:38
【问题描述】:

我需要通过行键的集合(在一个分区中)来查找多个实体。执行此操作的正确查询是什么?

【问题讨论】:

  • 我建议使用任务并行库并单独查询它们。

标签: .net azure azure-storage azure-table-storage


【解决方案1】:

这取决于您要优化什么。事实证明,指定多个行键,即使它们都在同一个分区中,也会导致分区扫描。查询优化器不足以处理 OR 查询。分区扫描可能需要数十到数百毫秒,具体取决于分区的大小。它总是比点查询慢。

如果您想优化速度,您应该分别执行每个查询。不要使用任务并行库,使用 begin/end 函数,它们的扩展性更好。

如果延迟不是问题,请执行 OR 查询。它会更慢,但它会算作一次交易,因此会更便宜。

【讨论】:

  • 嘿,什么是开始/结束功能?它们在 2016 年仍然有意义吗?
  • Begin/End 函数是以beginend 开头的函数:)。它们是老式的异步调用。我有一段时间没有使用这些库了,所以我不知道它们是否仍然相关 - 它们可能已被 Async-style Task 返回函数所取代。此外,查询优化器可能在过去近 5 年中变得更好。
【解决方案2】:

仅通过 rowkey 查询的问题(我正在解释要暗示的原始问题):您最终会进行表扫描,因为该 rowkey 可能存在于任何分区中。而且,如果您单独执行这些查询,您最终会为每个查询进行表扫描(即使使用任务并行库,正如@GlennFerrieLive 在对原始问题的评论中所建议的那样)。

您可以使用$filter(如this article 中所述)或离散的行键列表(过滤器内限制为 15 个单独的比较)指定行键的范围。最终应该只进行一次表扫描,但仍然...进行表扫描。

如果可以在查询中指定分区键,您应该这样做,因为它会使您的查询返回得更快。好的,快得多是相对的,因为我不知道您存储的数据量。

编辑:每次通过评论更新,因为您知道 partitionkey,您可以按照上面的指导在单个过滤器中指定行键范围或离散行键。或者...如果您有更多的行键,您可以考虑通过 TPL 执行这些(考虑到没有表扫描,现在这很有意义),或者作为每个过滤器的单个行键,或者分组到范围或过滤列表中。

【讨论】:

  • 我知道分区键,我需要在一个分区中通过多个行键查询。
  • 请注意(正如 breischi 在他/她的回答中指出的那样),对多个行键的 OR 查询会导致分区扫描。根据分区的大小,这可能非常糟糕。
【解决方案3】:

您可以在运行时创建过滤器字符串,并在异步情况下运行 ExecuteQuery 或 ExecuteQuerySegmentedAsync。例如在 C# 中:

string queryFilter = $"(PartitionKey eq '{<PK name>}') and" +
                $"({string.Join(" or", <YOUR LIST>.Select(tl => $"(RowKey eq '{<the property>}')"))})";

var query = new TableQuery<ExternalTranslationEntity>().Where(queryFilter).Take(<e.g yourList>.Count).
                Select(new List<string> { nameof(<if you want specific columns>) });

            TableContinuationToken? token = null;
            do
            {
                var segment = await _translationsTable.ExecuteQuerySegmentedAsync(query, token);

                if (segment.Results.Any())
                {
                    segment.Results.ForEach(r =>
                    {
                        //do whaterver you want
                    });
                }
                token = segment.ContinuationToken;
            } while (token != null);

【讨论】:

    猜你喜欢
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多