嗨,我有一点小麻烦,试图找到一个简单的解释绑定感知光标匹配在甲骨文..。是绑定感知游标匹配,基本上是让Oracle使用绑定变量监视查询,并查看在使用某些变量时CPU是否有所增加。然后,通过这样做,它几乎会生成一个更合适的执行计划,比如一个完整的表扫描,然后将查询标记为bind感知,那么下一次执行查询时,可以选择两个执行计划?任何帮助都将不胜感激!干杯!
发布于 2014-03-18 23:31:34
在最简单的情况下,假设您有一个ORDERS表。该表中有一个status列。只有少数几个status值,其中一些非常非常流行,而另一些则非常罕见。假设表有1000万行。就我们的目的而言,假设93%是“完全”的,5%是“取消”的,其余的2%是分散在跟踪订单流的8个不同状态之间(不完全、完全、在履行中、在运输中等等)。
如果表中有最基本的统计信息,优化器知道有1000万行和10个不同的状态。它不知道某些status值比其他值更受欢迎,因此它猜测每个状态对应于100万行。所以当它看到这样的查询时
SELECT *
FROM orders
WHERE status = :1它猜测,无论绑定变量值如何,它都需要从表中提取100万行,因此它决定使用完整的表扫描。
现在,一个人想知道甲骨文为什么这么傻,当他向处于中间状态的几个orders请求时,他会做一个完整的表扫描--很明显,在那里进行索引扫描会更好。这个人意识到优化器需要更多的信息,以了解某些status值比其他值更受欢迎,因此人类决定收集直方图(有些选项也会导致Oracle自动地在某些列上收集直方图,但我忽略了这些选项,以尽量保持故事的简单性)。
一旦直方图被收集,优化器就知道status值是高度倾斜的--有很多已完成的订单,但在中转订单中却很少。如果它看到一个使用文字而不是绑定变量的查询,即
SELECT *
FROM orders
WHERE status = 'IN TRANSIT'vs
SELECT *
FROM orders
WHERE status = 'COMPLETED'然后,优化器很容易决定在第一种情况下使用索引,在第二种情况下使用表扫描。但是,当您有一个绑定变量时,优化器的工作更加困难--如何确定是使用索引还是进行表扫描……
Oracle的第一个解决方案被称为“绑定变量窥视”。在这种方法中,当优化器看到以下内容时
SELECT *
FROM orders
WHERE status = :1如果它知道(因为status上的直方图)查询计划应该依赖于为绑定变量传入的值,Oracle“窥视”传入的第一个值,以确定如何优化语句。如果第一个绑定变量值是“正在传输”,则将使用索引扫描。如果第一个绑定变量值是'COMPLETE`‘,则将使用表扫描。
在很多情况下,这种方法效果很好。很多查询实际上只对非常流行或非常罕见的值有意义。在我们的例子中,任何人都不太可能真正想要一个包含900万份完整订单的列表,但有些人可能希望在一个不同的过渡状态中列出几千个订单。
但是绑定变量窥视在其他情况下并不有效。如果您的系统中,应用程序有时绑定非常流行的值,有时绑定非常罕见的值,则最终会出现应用程序性能严重依赖于谁首先运行查询的情况。如果第一个运行查询的人使用非常罕见的值,则会生成并缓存索引扫描计划。如果第二个运行查询的人使用非常常见的值,则将使用缓存的计划,您将得到一个需要花费很长时间的索引扫描。如果角色反转,第二个人使用罕见的值,获取执行全表扫描的缓存计划,并必须扫描整个表以获得他们感兴趣的几百行。这种不确定的行为往往会让DBA和开发人员抓狂,因为它很难诊断,并且可能导致一些奇怪的解释-- Tom有一个很好的客户总结如果星期一早上下雨,他们需要在下午重新启动数据库。的例子。
绑定感知游标匹配是解决绑定变量窥视问题的方法。现在,当Oracle看到查询时
SELECT *
FROM orders
WHERE status = :1并且看到在status上有一个直方图,它表明一些值比其他值更常见,它足够聪明地使游标“绑定感知”。这意味着,当绑定IN满足值时,优化器足够聪明地得出这是罕见的值之一,并给出索引计划。当绑定一个完整的值时,优化器就足够聪明地得出结论,这是一个常见的值,并通过表扫描给出了计划。因此,优化器现在知道对于同一个查询有两个不同的计划,当它看到一个新的bind值,比如在传输时,它会检查这个值是否与它以前看到的其他值相似,或者给出一个现有的计划,或者创建另一个新的计划。在这种情况下,它将决定在传输过程中与执行中的计划大致相同,因此它使用索引扫描来重复使用计划,而不是生成第三个查询计划。希望这会使每个人都得到他们喜欢的计划,而不必每次绑定变量值更改时都生成和缓存查询计划。
当然,在现实中,有许多额外的警告,角落的情况,考虑,和复杂,我是有意(和无意)在这里美化。但这是优化器试图实现的基本思想。
https://stackoverflow.com/questions/22492332
复制相似问题