4

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

4

3 回答 3

5

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

如果您想优化速度,您应该分别执行每个查询。不要使用任务并行库,使用开始/结束函数,它们可以更好地扩展。

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

于 2012-05-22T04:08:01.667 回答
3

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

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

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

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

于 2012-05-22T03:27:06.987 回答
0

您可以在运行时创建过滤器字符串,并在异步情况下运行 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);
于 2020-05-07T12:02:36.573 回答