0

假设以下查询:

PartitionKey==1 AND (RowKey==A OR RowKey==B)

甚至这个:

(PartitionKey==1 AND RowKey==A) OR (PartitionKey==2 AND RowKey==B)

这些中的任何一个都会导致扫描吗?

我问是因为这个 PDC 谈话表明它确实:

https://channel9.msdn.com/Events/PDC/PDC09/SVC09

特别是在 27:30,演讲者和幻灯片状态:

键上的“或”谓词 => 没有查询优化 => 导致扫描

这在 29:30 再次重申,建议使用并行查询。在网上搜索后,我也发现了这个线程:

https://social.msdn.microsoft.com/forums/azure/en-us/d7765773-74b8-4860-b07c-b9731a2210c7/performance-of-range-queries-on-partition-keys-and-row-keys

查询中的“OR”目前尚未优化,但正如我上面提到的,我们对此提出了功能要求。

现在所有这些信息都有 7-8 年的历史,而且可能已经发生了变化。上一个链接表明这是一个功能请求,今天它可能已经发生了。有吗?

如果它确实导致扫描,为什么?鉴于两个所需元素的唯一键都是已知的,扫描一个或多个分区的技术原因是什么?

考虑一个场景,其中一个人试图获取数百/数千个实体,其中每个实体的 Partition+RowKey 是预先知道的。执行单个查询以并行获取每个实体是否更快,或者使用“OR”谓词对每个调用进行批处理以最小化并行查询的数量?

最后一个问题 - 在单个查询中跨不同分区获取多个实体时是否有任何性能影响(问题顶部的第二个查询示例)?还是将查询保存在单个分区中更好(问题顶部的第一个查询示例)?25:20 的 PDC 谈话似乎表明,让查询将工作分配到多个分区实际上更好,这样工作可以并行进行。然而,讨论直接针对分区上的范围查询,而不是在两个不同的分区上使用“或”谓词。

谢谢!

** 编辑 **

我决定自己测试一下性能。对于测试,我创建了一个包含一个分区和一百万个实体的表。分区键为“0”,行键为“0”到“999999”的递增值。

运行测试时,我做了:

ServicePointManager.DefaultConnectionLimit = 1000;
servicePoint.UseNagleAlgorithm = false;
servicePoint.Expect100Continue = false;

在第一个测试中,我构建了一个如下所示的查询:

(PK eq '0' 和 RK eq '0') 或 (PK eq '0' 和 RK eq '500') 或 ... x400

总共有 400 个“或”组。行键增加了 500 以分散请求。

运行此查询需要 Azure 3:26。

接下来,我使用同一个查询的更简洁的形式进行了测试:

PK eq '0' 和(RK eq '0' 或 RK eq '500' 或 ... x400)

同样,总共有 400 个 'OR'd 表达式。再次将行键增加 500 以分散请求。

运行此查询需要 Azure 1:19。更好,但仍然完全不可接受的性能。

最后,我使用 TableOperation.Retrieve<> 测试了 400 个并行请求。

Azure 平均只需 3 秒即可并行运行所有这些查询。

显然,永远不要在表达式中使用“OR”并始终使用并行查询。IMO 'OR' 的性能是不可接受的,如果微软不对其进行优化,他们应该将其删除。

4

1 回答 1

0

PartitionKey==1 AND (RowKey==A OR RowKey==B) 这些是否会导致扫描?

是的,它将导致扫描。

azure 服务器会将此查询视为分区扫描。它将扫描分区等于“1”。

(PartitionKey==1 AND RowKey==A) OR (PartitionKey==2 AND RowKey==B) 这些是否会导致扫描?

天蓝色服务器会将此查询视为表扫描。它将扫描所有表并找到分区键。

考虑一个场景,其中一个人试图获取数百/数千个实体,其中每个实体的 Partition+RowKey 是预先知道的。执行单个查询以并行获取每个实体是否更快,或者使用“OR”谓词对每个调用进行批处理以最小化并行查询的数量?

我建议你可以做一个单独的查询来并行获取每个实体。由于 or 查询将导致表或范围扫描。

在单个查询中跨不同分区获取多个实体时是否有任何性能影响(问题顶部的第二个查询示例)?

据我所知,在单个查询中跨不同分区会导致表扫描,它会很慢。

还是将查询保存在单个分区中更好(问题顶部的第一个查询示例)?

据我所知,表扫描的速度如下:

点查询(一个分区键和行键)> 范围查询(一个分区键和行键范围)> 分区扫描(一个分区键和属性范围)> 表扫描(不包括分区键)

因此最好将查询保存在单个分区中。

于 2017-05-15T07:30:24.820 回答