标签归档:sql_profile

使用coe脚本固定执行计划和手工指定profile的outline的方式有什么区别?

测试目的: 1,假设下面的两个语句分别为A语句和B语句: A语句: select count(*) from lunar where extent_id=1; B语句: select /*+ FULL(lunar) */ count(*) from lunar where extent_id=1; 2,使用coe的脚本(在SQLT中可以知道整套coe脚本)手工为A语句指定B语句的执行计划,看看什么效果 (即,让原本正常走索引的A语句使用全表扫描的B语句的执行计划) 3,使用dbms_sqltune.import_sql_profile为A语句指定执行计划,看看什么效果 首先,做一个测试表: 在extent_id列上创建非唯一索引: 可以看到下面的语句正确的使用了索引(把这条语句称之为A语句): 我使用hint指定该语句必须走全表扫描,姑且把这条语句称为B语句: 找到A语句和B语句的sql_id: 使用coe的脚本来固定执行计划,291688323是B语句的执行计划: 根据提示执行COE_XFR_SQL_PROFILE_fvrmp2a2t38dc_291688323.sql脚本: 再次查询,验证一下A语句是否已经按照我们指定的那样采用了B语句的全表扫描的执行计划: 结论:我们的猜测是错误的,使用coe的脚本固定执行计划,必须是从该sql_id的已经有的所有执行计划中挑选其一,而不能凭空指定一个你认为合适的。 下面,我们使用其他方法固定SQL的执行计划。首先找出B语句的执行计划和outline: 使用下面的脚本为A语句指定B语句的outline: 结论: 1,使用coe的脚本固定执行计划,必须是从该sql_id的已经有的所有执行计划中挑选其一,而不能凭空指定一个你认为合适的。 因此,如果需要从某条sql已经执行过的执行计划中挑选一个合适的,那么coe的脚本简单轻巧,非常合适。 2,如果要手工构造一个该SQL语句从未使用的执行计划,可以采用dbms_sqltune.import_sql_profile的方式手工设置outline,从而改变执行计划。 在这种需求下,coe的脚本是无能为力的。

发表在 Performence Tuning | 标签为 , , | 5 条评论