如何通过outline为SQL语句指定执行计划
创建测试表
以用户jyu连接,创建测试表
SQL> conn jyu/jyu;
Connected. SQL> create table t (id number, name varchar2(100)); Table created. SQL> insert into t select rownum,object_name from dba_objects; 47391 rows created. SQL> commit; Commit complete. 创建索引
SQL> create index t_idx1 on t(id); Index created. 收集统计数据
SQL> exec dbms_stats.gather_table_stats('JYU','T'); PL/SQL procedure successfully completed.
执行计划
查看SQL语句执行计划
SQL> set autotrace traceonly
SQL> select * from t where id=1; Execution Plan
----------------------------------------------------------
Plan hash value: 3292636276 --------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 28 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX1 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("ID"=1) Note
-----
- outline "OLD_OUTLN" used for this statement Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
576 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL语句选择了使用索引的执行计划 使用Hint指定语句使用全表扫描的执行计划
SQL> explain plan for select /*+ full(t) */ * from t where id=1; Explained. SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2153619298 --------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 50 (2)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 1 | 28 | 50 (2)| 00:00:01 |
-------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------ 1 - filter("ID"=1) 13 rows selected.
使用outline固定执行计划
以sysdba连接数据库
SQL> conn /as sysdba
Connected. 分别为2个SQL语句创建outline
SQL> alter session set current_schema = jyu; Session altered. SQL> create or replace outline OLD_OUTLN for category TEMP_PLAN on select * from t where id=1; Outline created. SQL> create or replace outline NEW_OUTLN for category TEMP_PLAN on select /*+ full(t) */ * from t where id=1; Outline created. 交换SQL语句的outline
SQL> create private outline OLFROM from OLD_OUTLN; Outline created. SQL> create private outline OLTO from NEW_OUTLN; Outline created. SQL> update ol$ set hintcount=(select hintcount from ol$ where ol_name='OLTO') where ol_name='OLFROM'; 1 row updated. SQL> delete from ol$ where ol_name='OLTO'; 1 row deleted. SQL> update ol$ set ol_name='OLTO' where ol_name='OLFROM'; 1 row updated. SQL> commit; Commit complete. SQL> execute dbms_outln_edit.refresh_private_outline('OLTO'); PL/SQL procedure successfully completed. SQL> create or replace outline OLD_OUTLN from private OLTO for category GOOD_PLAN; Outline created. SQL> drop outline NEW_OUTLN; Outline dropped.
设置使用指定的outlines
有两种方式可在全局设置使用outline 方式一:使用alter system设置(数据库重启后失效)
SQL> conn / as sysdba
Connected.
SQL> alter system set use_stored_outlines=GOOD_PLAN; System altered. 方式二:通过trigger设置(数据库重启仍然有效)
SQL> create or replace trigger enable_outlines_trig
--Ref : How to Enable USE_STORED_OUTLINES Permanently (Doc ID 560331.1)
after startup on database
begin
execute immediate('alter system set use_stored_outlines=GOOD_PLAN');
end;
/
检查SQL语句执行计划
SQL> conn jyu/jyu
Connected.
SQL> set autotrace traceonly
SQL> select * from t where id=1; Execution Plan
----------------------------------------------------------
Plan hash value: 2153619298 --------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 50 (2)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 1 | 28 | 50 (2)| 00:00:01 |
-------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("ID"=1) Note
-----
- outline "OLD_OUTLN" used for this statement Statistics
----------------------------------------------------------
34 recursive calls
145 db block gets
269 consistent gets
0 physical reads
576 redo size
576 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
1 rows processed
outline生效,SQL语句执行了全表扫描。
#!/bin/bash if [ $# -lt 3 ]; then
cat <<EOF
Fix given SQL plan using given sql in file
usage: fix_plan.sh <hash_value> <hinted_sql_file> <owner>
examples: fix_plan.sh 716428968 good.sql ALEX
EOF
exit 1
fi HASH_VALUE=$1
SQL_FILE=$2
OL_OWNER=$3 echo "HASH_VALUE : $HASH_VALUE"
echo "SQL_FILE : $SQL_FILE"
echo "OL_OWNER : $OL_OWNER"
echo "" #Create outline by hash_value
function create_ol_from_hashvalue {
HASH_VALUE=$1
OL_NAME=$2
OL_OWNER=$3 #generate create outline sql
#I didn't use dbms_outln.create_outline, because it cannot create given name outline
# and there's no hash value in V$SQL and DBA_OUTLINES to associate the two
# according to "How To Match a SQL Statement to a Stored Outline (Doc ID 743312.1)"
sqlplus -S "/ as sysdba" > /tmp/tmp_$OL_NAME.sql <<EOF
set feedback off
set serveroutput on size unlimited
declare
v_sqltext varchar2(32000);
begin
--get sql text
select dbms_lob.substr(SQL_FULLTEXT, 30000, 1 ) into v_sqltext from v\$sql where hash_value = $HASH_VALUE and rownum=1; dbms_output.put_line('alter session set current_schema = $OL_OWNER;');
v_sqltext := 'create or replace outline $OL_NAME for category TEMP_PLAN on ' || chr(10) || v_sqltext || chr(10) ||';';
dbms_output.put_line(v_sqltext);
dbms_output.put_line('exit;');
end;
/
EOF sqlplus -S "/ as sysdba" @/tmp/tmp_$OL_NAME.sql
} #Create outline from sql file
function create_ol_from_sqlfile {
SQL_FILE=$1
OL_NAME=$2
OL_OWNER=$3 #generate create outline sql
cat > /tmp/tmp_$OL_NAME.sql <<EOF
alter session set current_schema = $OL_OWNER;
create or replace outline $OL_NAME for category TEMP_PLAN on
`cat $SQL_FILE`
exit;
EOF sqlplus -S "/ as sysdba" @/tmp/tmp_$OL_NAME.sql } #Exchange outlines, make GOOD_SQL plan to GOOD_PLAN category
#Ref: How to Edit a Stored Outline to Use the Plan from Another Stored Outline (Doc ID 730062.1)
function exchange_outline {
OL1=$1
OL2=$2
OL_OWNER=$3 sqlplus -S "/ as sysdba" <<EOF
set feedback off
alter session set current_schema = $OL_OWNER;
create private outline OLFROM from $OL1;
create private outline OLTO from $OL2;
update ol$ set hintcount=(select hintcount from ol$ where ol_name='OLTO') where ol_name='OLFROM';
delete from ol$ where ol_name='OLTO';
update ol$ set ol_name='OLTO' where ol_name='OLFROM';
commit;
execute dbms_outln_edit.refresh_private_outline('OLTO');
create or replace outline $OL1 from private OLTO for category GOOD_PLAN;
drop outline $OL2;
exit;
EOF } #display outline
function display_outline {
OL_NAME=$1
OL_OWNER=$2 sqlplus -S "/ as sysdba" <<EOF
set pagesize 1000 linesize 160
set long 32000
col hint format a55
col join_pos format a45
col owner format a12
col name format a18
col ts format a14
col h format 999
col category format a12
col sql_text format a80
col used format a6 select name, sql_text, category, used, to_char(TIMESTAMP, 'YY-mm-dd hh24:MI')
from dba_outlines
where name = '$OL_NAME' and OWNER = '$OL_OWNER'; select ol_name name, category, hint#, stage# stage, hint_text hint, join_pred join_pos
from outln.ol\$hints
where ol_name = '$OL_NAME'
order by ol_name, hint#;
exit;
EOF
} #main function
echo "1. Create outline OL_$HASH_VALUE for SQL $HASH_VALUE"
create_ol_from_hashvalue $HASH_VALUE OL_$HASH_VALUE $OL_OWNER echo "2. Create outline OL_TEMP for SQL in $SQL_FILE"
create_ol_from_sqlfile $SQL_FILE OL_TEMP $OL_OWNER echo "3. Exchange outline OL_$HASH_VALUE with OL_TEMP, and drop OL_TEMP"
exchange_outline OL_$HASH_VALUE OL_TEMP $OL_OWNER echo "4. Display final outline for SQL $HASH_VALUE : OL_$HASH_VALUE in category GOOD_PLAN "
display_outline OL_$HASH_VALUE $OL_OWNER
如何通过outline为SQL语句指定执行计划的更多相关文章
- oracle中查看sql语句的执行计划
1.在pl/sql中打开cmd命令容器 2.在cmd命令窗口中输入:explain plan for select * from t; 3.查看sql语句的执行计划:select * from tab ...
- 【Oracle】三种方式查看SQL语句的执行计划
查看执行计划的方式有三种: EXPLAIN PLAN .V$SQL_PLAN .SQL*PLUS AUTOTRACE 1.EXPLAIN PLAN: 显示执行相应语句时可以使用的理论计划 读取执行计划 ...
- SQL语句的执行计划(oracle表的三种链接方式)
SQL语句我们写完之后,就是分析其优化,这就要求我们了解到底数据是怎么存储. 首先我们需要了解,表链接的几种方式 nested loop join sort merge join hash join ...
- 【测试】使用hr用户下的employees表写一条SQL语句,执行计划走索引全扫描
SQL> select count(*) from employees; COUNT(*) ---------- Execution Plan ------------------------- ...
- 【测试】并使用scott用户下的emp表写一条SQL语句,执行计划走唯一索引
SQL; SAL ---------- Execution Plan ---------------------------------------------------------- ------ ...
- ORACLE数据库SQL语句的执行过程
SQL语句在数据库中处理过程是怎样的呢?执行顺序呢?在回答这个问题前,我们先来回顾一下:在ORACLE数据库系统架构下,SQL语句由用户进程产生,然后传到相对应的服务端进程,之后由服务器进程执行该SQ ...
- 官方文档:11G新特性SQL PLAN BASLINE 执行计划基线
什么是SQL执行计划管理? SQL计划管理(SQL plan management)是一咱预防机制,记录和评估SQL语句的执行计划.SQL plan management的主要功能是sql plan ...
- 详细分析SQL语句逻辑执行过程和相关语法
本文目录: 1.SQL语句的逻辑处理顺序 1.2 各数据库系统的语句逻辑处理顺序 1.2.1 SQL Server和Oracle的逻辑执行顺序 1.2.2 MariaDB的逻辑执行顺序 1.2.3 M ...
- mybatis下使用log4j打印sql语句和执行结果
转载自:https://www.cnblogs.com/jeevan/p/3493972.html 本来以为很简单的问题, 结果自己搞了半天还是不行; 然后google, baidu, 搜出来各种方法 ...
随机推荐
- ggplot笔记002——qplot()函数
qplot()函数 一年前就听说过ggplot,很多人都说ggplot强大,ggplot无所不能,从今天开始就让我们一起来见证一下这个神奇的R包. 首先要加载ggplot2: 1 if(!suppre ...
- 一个专为电商定制的域名.shop
2.73亿元人民币获得.shop域名的经营权,使shop域名成为最高节拍价的顶级域名.虽然最终“最高节拍价”被web域名打破,但在电商届域名里shop还是王者.shop作为一个主要面向线上.线下销售实 ...
- myEclipse 导入maven项目时报错
1.先右击项目,build Path 查看是否是某个JAR出了错.去掉无用的JAR 以及修改对应的JDK版本 2.检查src源文件,查看是否是源文件出了错.发现,还真的是 导入的包上面,报错:The ...
- python常见的PEP8规范
1. 括号中使用垂直隐式缩进或使用悬挂缩进 缩进 每级缩进用4个空格 示例: (垂直隐式缩进)对准左括号 def function_name(var_one,var_two, var_three,va ...
- devstack apache2/keystone 没有启动
在devstack中./rejoin-stack.sh 发现apache2/keystone 没有启动 单单手动启动apach2服务之后keystone并没有启动 sudo service apach ...
- mysql: instr 多个字段 like数据
你是否一直在寻找比MySQL的LIKE语句更高效的方法的,下面我就为你介绍几种. SELECT * FROM `order_shop` where instr(uuid, 'b') > 0 g ...
- J2EE配置tomcat
- mpv 播放器
https://mpv.io/ Mac版本: 官网: https://mpv.io/ https://mpv.io/installation/ 下载: http://sva.wakku.to/~chr ...
- 51nod 1099 贪心/思维
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1099 1099 任务执行顺序 基准时间限制:1 秒 空间限制:13107 ...
- 三张图较为好理解JavaScript的原型对象与原型链
最近从网上看到别人详细得讲解了js的原型对象和原型链,看完感觉是看得最清晰的一个,于是,摘录到自己博客里 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与_ ...