从执行计划看,此时是对索引IDX_T1走的索引范围扫描,而且Oracle评估出来执行这个索引范围扫描所返回结果集的Cardinality的值为3。并注意到“Peeked Binds”部分的内容为“1 - :X (NUMBER): 999 2 - :Y (NUMBER): 1000”,这说明Oracle在硬解析上述SQL的过程中确实使用了绑定变量窥探,且做“窥探”这个动作时看到的绑定变量x和y的具体输入值分别为999和1000。
现在保持x不变,将y修改为60000:
zx@MYDB>exec :y := 60000;
PL/SQL procedure successfully completed.
zx@MYDB>select count(*) from t1 where object_id between :x and :y;
COUNT(*)
----------
58180
从上述查询结果可以看出上述SQL对应的VERSION_COUNT的值为1,列EXECUTIONS的值为2,这说明Oracle在第二次执行该SQL时用的是软解析。
从执行计划上可以看出,此时SQL的执行计划依然走的是对索引IDX_T1走的索引范围扫描,并且“Peeked Binds”部分的内容依然为“1 - :X (NUMBER): 999 2 - :Y (NUMBER): 1000”。
之前在不使用绑定变量时,我们已经知道Oracle在执行“between 999 and 60000”条件时走的是索引快速全扫描。但第二次执行使用绑定变量等价改写的SQL时,即使绑定变量x和y的具体的输入值是999和60000,但Oracle这里依然沿用该SQL之前硬解析时(对应绑定量x和y的具体的输入值是999和1000)所产生的解析树和执行计划,而不再重复执行“窥探”的动作。