我们知道,由于绑定变量窥视(Bind Peeking)功能,SQL文在进行硬解析(Hard Parse)时,会代入绑定变量的值来估算选择基数(cardinality )并做成执行计划,而相同的SQL文以后在执行过程中,都会共享初次执行时做成的执行计划。
如果表的数据分布不均或者数据倾斜时,用于估算的变量值和以后执行中的用到的变量值估算选择基数(cardinality )差异很大时,通过绑定变量窥视(Bind Peeking)功能做成的执行计划,针对某些变量值的执行可能都是最优的,甚至可能引起很严重的性能问题。
因此,优化器在11.1以后的版本上,为了解决绑定变量窥视(Bind Peeking)的问题,推出了自适应游标共享(Adaptive Cursor Sharing 以后简称ACS)功能,使包含绑定变量的同一条SQL语句在多次执行时,不会盲目的共享执行计划,而会根据绑定变量值和执行过程中收集信息的反馈,可以使用多个不同执行计划,避免性能问题。
下面我们将通过几个例子来进一步了解ACS功能。
本文是自适应游标共享(Adaptive Cursor Sharing)的第一部分主要介绍当自适应游标共享(Adaptive Cursor Sharing)无效时的状况:
首先,我们看一下在绑定变量窥视(Bind Peeking)功能有效,但是自适应游标共享功能无效的情况下,执行以下SQL文的动作。(基于10.2.0.5版本测试)
0.准备测试用表和数据
1.首先我们指定变量值为3,执行下面的SQL文
2.因为绑定变量窥视(Bind Peeking)功能的影响,所以硬解析选择执行计划时, 会把绑定变量值3代入到SQL文中计算基数,SQL文在10000条数据中选择了30条数据, 所以,选择了索引IND1进行INDEX RANGE SCAN。
3.我们再指定变量值为9,再次执行下面的SQL文。 虽然这时候SQL文在10000条数据中选择了9000条数据,选择率高达90%,但是因为SQL文已经解析过了,所以会继续用之前的执行计划,E-Rows还是30,使用用INDEX RANGE SCAN.
4.我们再次指定变量值为9,执行下面的SQL文。 这时候SQL文还是在10000条数据中选择了9000条数据,但是因为SQL文已经解析过了,所以会继续用之前的执行计划,使用用INDEX RANGE SCAN
5.无论以后指定变量值是什么,执行计划都会用最初做成的执行计划。 这样通过绑定变量窥视(Bind Peeking)功能做成的执行计划,针对某些变量值的执行可能都是最优的,甚至可能引起很严重的性能问题。
本文是自适应游标共享(Adaptive Cursor Sharing)的第一部分,主要介绍ACS的概述和当ACS无效时会产生的问题例子。
将在第二部分中介绍ACS有效时的状况例子,以及ACS处理流程。