Azure 表查询中的最大 $filter 比较

Posted

技术标签:

【中文标题】Azure 表查询中的最大 $filter 比较【英文标题】:Max $filter comparisons in an Azure Table Query 【发布时间】:2017-10-13 01:31:52 【问题描述】:

这个页面 (https://docs.microsoft.com/en-us/rest/api/storageservices/querying-tables-and-entities) 说:

请注意,$filter 字符串中的离散比较不能超过 15 个。

但是在我的实验中,我已经达到了这个限制并且没有任何副作用。例如,这是来自 Azure 存储资源管理器:

storageacct/table 的统计信息(“PartitionKey eq '1' or PartitionKey eq '2' or PartitionKey eq '3' or PartitionKey eq '4' or PartitionKey eq '5' or PartitionKey eq '6' or PartitionKey eq '7 ' 或 PartitionKey eq '8' 或 PartitionKey eq '9' 或 PartitionKey eq '10' 或 PartitionKey eq '11' 或 PartitionKey eq '12' 或 PartitionKey eq '13' 或 PartitionKey eq '14' 或 PartitionKey eq '15' 或PartitionKey eq '16' 或 PartitionKey eq '17' 或 PartitionKey eq '18' 或 PartitionKey eq '19' 或 PartitionKey eq '20' 或 PartitionKey eq '21' 或 PartitionKey eq '22' 或 PartitionKey eq '23' 或 PartitionKey eq '24' 或 PartitionKey eq '25' 或 PartitionKey eq '26' 或 PartitionKey eq '27' 或 PartitionKey eq '28' 或 PartitionKey eq '29' 或 PartitionKey eq '30' 或 PartitionKey eq '31' 或 PartitionKey eq '32 ' 或 PartitionKey eq '33' 或 PartitionKey eq '34' 或 PartitionKey eq '35' 或 PartitionKey eq '36' 或 PartitionKey eq '37' 或 PartitionKey eq '38' 或 PartitionKey eq '39' 或 PartitionKey eq '40' 或分区表y eq '41'"): 0 个实体

鉴于 15 个比较限制,我预计此 $filter 会导致请求失败。

如果我需要以某种方式解释“15 个离散比较”,我尝试使用各种和/或组合进行此查询。它总是成功的。

上一代 Azure 表 API 的限制是否已不存在?

$filter 还有其他限制吗?比如最大字符串长度?

谢谢

** 编辑 **

我一直在做更多的试验。假设Development Storage Emulator和真实的服务一样,一个查询中可以使用的比较运算符的数量并不是一个固定的数量。以下是一些实验结果,它们给出了成功的结果,当递增 1 时会导致错误:

(PK==V) and ((RK==V) or (RK==V) ... 97x) // 98 次比较,97 次非 PK 比较 (PK==V and RK==V) or (PK==V and RK==V) ... 97x // 194 次比较,97 次非 PK 比较 (RK==V) 或 (RK==V) ... 98x // 98 次比较,98 次非 PK 比较 (PK==V) 或 (PK==V) ... 98x // 98 次比较,0 次​​非 PK 比较 (PK==V and RK==V and Prop=V) or (PK==V and RK==V and Prop=V) ... 93x // 279 次比较,186 次非 PK 比较

我不确定从中得出什么结论。我可以安全地执行 (PK==V and RK==V) or'd 97 次,但我可以执行 (RK==V) or'd 98 次。我已经用相同的值和不同的值以及其他比较运算符进行了测试,而不仅仅是等于。

有了这些结果,我们怎么可能知道服务器会根据查询字符串返回错误?

数字 15 在哪里发挥作用?

** 编辑 **

我刚刚在实时存储帐户上尝试了所有测试,发现没有最大值。事实上,我能够继续成功添加运算符,直到它开始返回:

远程服务器返回错误:(414) Request-URI Too Long.

所以我从存储模拟器获得的所有这些随机结果显然不适用于实时服务。而且15个比较限制根本不存在? (推测)

经过反复试验,当完整 URI 大约有 32768 (32KB) 个字符长时,我似乎开始收到 414 错误。这是一个完全编码的 URL,包括所有其他参数、方案、主机名等。我认为没有一种可靠的方法来预先计算 ExecuteQuery 生成的确切 URI 长度,所以我想可以只拆分请求开始在大约 32500 个字符的 $filter 字符串之后?然后不要指望它可以与存储模拟器一起使用...

【问题讨论】:

过去我发现模拟器和真实服务之间存在差异,尤其是在服务方面。您可以针对真实服务进行测试并发布结果吗? 【参考方案1】:

我还使用 REST API 和客户端库对其进行了测试。我还发现不存在 15 个离散比较限制。我可以添加很多比较,直到达到 URL 长度限制。这是我测试的。

    Table REST API,1000 多次 PK 比较。 Table REST API,1000 多次不同列的比较。 Table 客户端库,1000 多次 PK 比较。 Table 客户端库,1000 多个不同列的比较。

在 Azure 表客户端库文档中,我没有找到 15 次离散比较的限制。限制可能已过时。 Table​Query.​Filter​String Property

您可以对以下文档发表评论,以获得文档所有者的官方回复。

Querying Tables and Entities

【讨论】:

【参考方案2】:

我只是想回应其他人的观察。

似乎没有 15 个比较限制。

在表存储上构建高性能应用程序需要尽可能少地往返服务,这意味着在单个请求中发送尽可能多的工作让服务器完成。

很遗憾,真正的限制没有在任何地方公布,而且我发现的一个限制(15 次比较)并不是真正的限制。

在我的测试中我观察到:

32,684 url​​ 长度产生 200 好吧 32,685 url 长度产生 414 URL TOO LONG 为已知键发送的每个行键比较都得到遵守,并在 HTTP 响应中产生结果。没有发现任何限制。

【讨论】:

【参考方案3】:

我联系了相应的 Azure 产品组,并确认 Azure 代码中不存在 15 项限制。将有一个文档更新来反映这一点。很抱歉这里的混乱!

【讨论】:

以上是关于Azure 表查询中的最大 $filter 比较的主要内容,如果未能解决你的问题,请参考以下文章

比 Bloom Filter 节省25%空间!Ribbon Filter 在 Lindorm 中的应用

mysql比较两个表中的某个字段大小,并取最大值

mysql 多表查询 比较两个字段最大、最小值,并显示对应字段

Azure 数据仓库中的表详细信息

使用 map/filter 在 Pyspark 中的 RDD 中查找最大元素

带有字段比较结果的django注释查询集