Azure Table 查询 'OR' 谓词会导致扫描吗?
Do Azure Table Query 'OR' Predicates Cause a Scan?
假设以下查询:
PartitionKey==1 AND (RowKey==A OR RowKey==B)
甚至这样:
(PartitionKey==1 AND RowKey==A) 或 (PartitionKey==2 AND RowKey==B)
是否会导致扫描?
我问是因为这个 PDC 谈话表明确实如此:
https://channel9.msdn.com/Events/PDC/PDC09/SVC09
特别是在 27:30 扬声器和幻灯片状态:
"OR" predicates on keys => no query optimization => results in scan
29:30 再次重申这一点,建议使用并行查询。在网上搜索后,我还找到了这个帖子:
"OR" in queries is not optimized at present but as I mentioned above, we have had feature requests for that.
现在所有这些信息都有 7-8 年的历史了,也许已经改变了。之前的 link 表示这是一个功能请求,今天可能已经发生了。有吗?
如果它确实导致扫描,为什么?鉴于两个所需元素的唯一键都是已知的,扫描一个或多个分区的技术原因是什么?
考虑一个场景,其中一个人试图获取 hundreds/thousands 个实体,其中每个实体的 Partition+RowKey 是事先已知的。是执行单个查询以并行获取每个实体更快,还是使用 'OR' 谓词对每次调用进行批处理以最大限度地减少并行查询的数量?
最后一个问题 - 在单个查询中跨不同分区获取多个实体时是否有任何性能影响(问题顶部的第二个查询示例)?或者将查询保留在单个分区中更好(问题顶部的第一个查询示例)?时间 25:20 的 PDC 谈话似乎表明实际上更好的做法是使查询将工作分配到多个分区,以便工作可以并行进行。然而,讨论直接针对分区的范围查询,而不是在两个不同的分区上使用 'OR' 谓词。
谢谢!
** 编辑 **
我决定亲自测试性能。对于测试,我创建了一个 table,其中包含一个分区和一百万个实体。分区键是“0”,行键是从“0”到“999999”的递增值。
当 运行我做的测试时:
ServicePointManager.DefaultConnectionLimit = 1000;
servicePoint.UseNagleAlgorithm = false;
servicePoint.Expect100Continue = false;
在第一个测试中,我构造了一个如下所示的查询:
(PK eq '0' and RK eq '0') or (PK eq '0' and RK eq '500') or ... x400
共有 400 个 'OR' 组。行键增加了 500 以稍微分散请求。
Azure 3:26 完成了此查询 运行。
接下来我使用同一个查询的更简洁的形式进行了测试:
PK eq '0' 和(RK eq '0' 或 RK eq '500' 或 ... x400)
同样,共有 400 个 'OR'd 表达式。再次将行键递增 500 以稍微分散请求。
Azure 1:19 完成了此查询 运行。更好,但仍然完全无法接受table 性能。
最后,我使用 TableOperation.Retrieve<> 测试了 400 个并行请求。
Azure 平均只用了 3 秒就可以并行 运行 所有这些查询。
显然,永远不要在表达式中使用 'OR' 并始终使用并行查询。 IMO 'OR' 的性能是 unacceptable 如果微软不优化它应该删除它。
PartitionKey==1 AND (RowKey==A OR RowKey==B) Do either of these result in a scan?
是的,它会导致扫描。
Azure服务器会将此查询视为分区扫描。它将扫描等于'1'的分区。
(PartitionKey==1 AND RowKey==A) OR (PartitionKey==2 AND RowKey==B) Do either of these result in a scan?
Azure 服务器会将此查询视为table 扫描。它将扫描所有 table 并找到分区键。
Consider a scenario where one is trying to fetch hundreds/thousands of entities where only the Partition+RowKey of each entity is known in advance. Is it faster to do an individual query to fetch each entity in parallel, or use an 'OR' predicate to batch multiple per call to minimize the number of parallel queries?
我建议您可以进行单独的查询以并行获取每个实体。由于 or 查询将导致 table 或范围扫描。
Are there any performance implications when fetching multiple entities across different partitions in a single query (2nd query example at top of question)?
据我所知,在一次查询中跨不同分区会造成table扫描,会很慢。
Or is it better to keep the query in a single partition (1st query example at top of question)?
据我所知,table扫描的速度如下:
Point Query(一个partitionkey和row key) > Range Query(一个partitionkey和rowkey的range) > Partition Scan(一个partitionkey和range 属性) > Table Scan(不包括分区键)
因此最好将查询保留在单个分区中。
假设以下查询:
PartitionKey==1 AND (RowKey==A OR RowKey==B)
甚至这样:
(PartitionKey==1 AND RowKey==A) 或 (PartitionKey==2 AND RowKey==B)
是否会导致扫描?
我问是因为这个 PDC 谈话表明确实如此:
https://channel9.msdn.com/Events/PDC/PDC09/SVC09
特别是在 27:30 扬声器和幻灯片状态:
"OR" predicates on keys => no query optimization => results in scan
29:30 再次重申这一点,建议使用并行查询。在网上搜索后,我还找到了这个帖子:
"OR" in queries is not optimized at present but as I mentioned above, we have had feature requests for that.
现在所有这些信息都有 7-8 年的历史了,也许已经改变了。之前的 link 表示这是一个功能请求,今天可能已经发生了。有吗?
如果它确实导致扫描,为什么?鉴于两个所需元素的唯一键都是已知的,扫描一个或多个分区的技术原因是什么?
考虑一个场景,其中一个人试图获取 hundreds/thousands 个实体,其中每个实体的 Partition+RowKey 是事先已知的。是执行单个查询以并行获取每个实体更快,还是使用 'OR' 谓词对每次调用进行批处理以最大限度地减少并行查询的数量?
最后一个问题 - 在单个查询中跨不同分区获取多个实体时是否有任何性能影响(问题顶部的第二个查询示例)?或者将查询保留在单个分区中更好(问题顶部的第一个查询示例)?时间 25:20 的 PDC 谈话似乎表明实际上更好的做法是使查询将工作分配到多个分区,以便工作可以并行进行。然而,讨论直接针对分区的范围查询,而不是在两个不同的分区上使用 'OR' 谓词。
谢谢!
** 编辑 **
我决定亲自测试性能。对于测试,我创建了一个 table,其中包含一个分区和一百万个实体。分区键是“0”,行键是从“0”到“999999”的递增值。
当 运行我做的测试时:
ServicePointManager.DefaultConnectionLimit = 1000;
servicePoint.UseNagleAlgorithm = false;
servicePoint.Expect100Continue = false;
在第一个测试中,我构造了一个如下所示的查询:
(PK eq '0' and RK eq '0') or (PK eq '0' and RK eq '500') or ... x400
共有 400 个 'OR' 组。行键增加了 500 以稍微分散请求。
Azure 3:26 完成了此查询 运行。
接下来我使用同一个查询的更简洁的形式进行了测试:
PK eq '0' 和(RK eq '0' 或 RK eq '500' 或 ... x400)
同样,共有 400 个 'OR'd 表达式。再次将行键递增 500 以稍微分散请求。
Azure 1:19 完成了此查询 运行。更好,但仍然完全无法接受table 性能。
最后,我使用 TableOperation.Retrieve<> 测试了 400 个并行请求。
Azure 平均只用了 3 秒就可以并行 运行 所有这些查询。
显然,永远不要在表达式中使用 'OR' 并始终使用并行查询。 IMO 'OR' 的性能是 unacceptable 如果微软不优化它应该删除它。
PartitionKey==1 AND (RowKey==A OR RowKey==B) Do either of these result in a scan?
是的,它会导致扫描。
Azure服务器会将此查询视为分区扫描。它将扫描等于'1'的分区。
(PartitionKey==1 AND RowKey==A) OR (PartitionKey==2 AND RowKey==B) Do either of these result in a scan?
Azure 服务器会将此查询视为table 扫描。它将扫描所有 table 并找到分区键。
Consider a scenario where one is trying to fetch hundreds/thousands of entities where only the Partition+RowKey of each entity is known in advance. Is it faster to do an individual query to fetch each entity in parallel, or use an 'OR' predicate to batch multiple per call to minimize the number of parallel queries?
我建议您可以进行单独的查询以并行获取每个实体。由于 or 查询将导致 table 或范围扫描。
Are there any performance implications when fetching multiple entities across different partitions in a single query (2nd query example at top of question)?
据我所知,在一次查询中跨不同分区会造成table扫描,会很慢。
Or is it better to keep the query in a single partition (1st query example at top of question)?
据我所知,table扫描的速度如下:
Point Query(一个partitionkey和row key) > Range Query(一个partitionkey和rowkey的range) > Partition Scan(一个partitionkey和range 属性) > Table Scan(不包括分区键)
因此最好将查询保留在单个分区中。