一、set autotrace trace
disql下执行set autotrace trace开启AUTOTRACE功能,执行SQL语句,并打印实际的执行计划。
SQL> set autotrace trace
SQL> select a.employee_name, b.department_name from dmtest.t_emp a join dmtest.t_dept b on a.department_id = b.department_id and b.department_id=102;
目前看到的是数据库显示的执行计划
二、v$cachepln中获取执行计划
v$cachepln中保存了SQL缓冲区中的执行计划信息,在ini参数USE_PLN_POOL !=0时才统计。根据v$cachepln中的cache_item可以获取实际执行计划信息:
SQL> select cache_item, sqlstr from v$cachepln where sqlstr like 'select a.employee_name, b.department_name from dmtest.t_emp a join dmtest.t_dept b on a.department_id = b.department_id and b.department_id=102%';
SQL> alter session set events 'immediate trace name plndump level 140244262459496, dump_file ''/opt/dm/sqlplntest.log''';
查看dump的执行计划信息:
这个是真实的执行计划
有些是因为表中索引过多,优化器并没有走最优的执行计划,搜集统计信息和清理执行计划缓存也并不能解决问题,这时候需要绑定执行计划。有两种方式可以处理问题
1.通过改SQL select /*+index(TEST,IDX_TEST_ID) */* from test where id>1;
这种需要在应用去改,加hint的方式解决/*+index(表名,索引名) */
2.通hint注入的方式去改
sp_set_para_value(1,'ENABLE_INJECT_HINT',1); ----开启hint注入
Ø SQL 只能是语法正确的增删改查语句;
Ø SQL 会经过系统格式化,格式化之后的 SQL 和指定的规则名称必须全局唯一;
Ø HINT 一指定,则全局生效;
Ø系统检查 SQL 匹配时,必须是整条语句完全匹配,不能是语句中子查询匹配;
Ø可通过 SYSINJECTHINT 视图查看已指定的 SQL 语句和对应的 HINT。
--对指定SQL增加HINT
SF_INJECT_HINT('sql语句', '参数名(参数值)', '规则名', null,TRUE,TRUE);
实际应用:
SQL> SF_INJECT_HINT('select * from test where id>1;','INDEX(TEST,IDX_TEST_ID)','INJECT1','test injecting hint', TRUE,TRUE);指定该语句使用IDX_TEST_ID索引