做Azure表查询' OR'谓词导致扫描?

时间:2017-05-14 04:32:18

标签: azure-table-storage azure-tablequery

假设以下查询:

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,演讲者和幻灯片说明:

  

" OR"关于键的谓词=>没有查询优化=>扫描结果

这在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谈话似乎表明,实际上最好使查询将工作分配到多个分区,以便工作可以并行进行。然而,讨论直接针对分区上的范围查询,而不是使用' OR'谓词在两个不同的分区上。

谢谢!

**编辑**

我决定自己测试一下这个表现。为了测试,我创建了一个包含一个分区和一百万个实体的表。分区键是" 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个' OR'组。行键增加500以稍微分散请求。

Azure 3:26运行此查询。

接下来,我使用稍微简洁的同一查询进行测试:

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

同样总共有400个“或”表达式。并且行键再次增加500以稍微分散请求。

Azure 1:19运行此查询。更好,但仍然完全无法接受的表现。

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

平均花了3秒才能并行运行所有这些查询。

显然,永远不要使用' OR'在表达式中,始终使用并行查询。 IMO的表现是' OR'是不可接受的,微软应该删除它,如果他们不会优化它。

1 个答案:

答案 0 :(得分:0)

  

PartitionKey == 1 AND(RowKey == A OR RowKey == B)这些中的任何一个会导致扫描吗?

是的,它会导致扫描。

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

  

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

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

  

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

我建议您可以进行单独查询以并行获取每个实体。由于或查询将导致表或范围扫描。

  

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

据我所知,单个查询中的不同分区会导致表扫描,它会非常慢。

  

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

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

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

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