Oracle In-Clause 参数填充

Oracle In-Clause Parameter Padding

假设一个子句可以接受不同数量的绑定参数。在这种情况下,数据库可能很难缓存查询。基本上,每次传递不同数量的绑定参数时,都需要对查询进行硬解析。输入“参数填充”。参数填充将采用子句并将绑定数增加到最接近的 2^x 绑定数。

示例:

现在这两个查询可以共享相同的缓存计划。

问题: 2^x 绑定是否有合理的原因?为什么不是 3^x 或 5^x 以便需要更少的硬解析?这对于包含多个具有不同绑定的子句的查询特别有用。

有问题的具体数据库是Oracle 12c。对包含子句 in (1, 2, 3, 3) 的查询使用统计信息表明重复值不会出现在执行计划中。此外,对于需要 30 个绑定的查询,使用 stats 的运行效率与使用所需的确切 30 个值的子句或使用具有 100 个值的子句(其中最后一个值出现 70 次以上)一样有效。

有一个权衡:

如果您选择 5^x,那么对于 7 个参数,您的 IN-list 将有 25 个成员,而不仅仅是 8 个。查询将花费更长的时间到 运行 - 事实尾部值都相等无济于事。

请注意,您的 (1,2,3,3) 的 IN-list 的解释计划示例是无关紧要的。具有 hard-coded 值,而不是绑定变量。相关示例是 (:bind1, :bind2, :bind3, :bind4);当查询被解析时,优化器不能假定 :bind3 将始终等于 :bind4(很明显,这在一般情况下甚至不是真的)。​​

2^x 通常是“允许多少硬解析”和“查询速度有多快”之间的一个很好的权衡。否则你可以只使用一个查询,有 1000 个参数(允许的最大值)——为什么还要有多个这样的查询?