假设以下查询:
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 再次重申,建议使用并行查询。在网上搜索后,我也发现了这个线程:
查询中的“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' 的性能是不可接受的,如果微软不对其进行优化,他们应该将其删除。