假设以下查询:
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再次重申,建议使用并行查询。在搜索互联网后,我也找到了这个帖子:
" 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'是不可接受的,微软应该删除它,如果他们不会优化它。
答案 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)
因此最好将查询保留在单个分区中。