• 创建测试表

以用户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语句指定执行计划的更多相关文章

  1. oracle中查看sql语句的执行计划

    1.在pl/sql中打开cmd命令容器 2.在cmd命令窗口中输入:explain plan for select * from t; 3.查看sql语句的执行计划:select * from tab ...

  2. 【Oracle】三种方式查看SQL语句的执行计划

    查看执行计划的方式有三种: EXPLAIN PLAN .V$SQL_PLAN .SQL*PLUS AUTOTRACE 1.EXPLAIN PLAN: 显示执行相应语句时可以使用的理论计划 读取执行计划 ...

  3. SQL语句的执行计划(oracle表的三种链接方式)

    SQL语句我们写完之后,就是分析其优化,这就要求我们了解到底数据是怎么存储. 首先我们需要了解,表链接的几种方式 nested loop join sort merge join hash join ...

  4. 【测试】使用hr用户下的employees表写一条SQL语句,执行计划走索引全扫描

    SQL> select count(*) from employees; COUNT(*) ---------- Execution Plan ------------------------- ...

  5. 【测试】并使用scott用户下的emp表写一条SQL语句,执行计划走唯一索引

    SQL; SAL ---------- Execution Plan ---------------------------------------------------------- ------ ...

  6. ORACLE数据库SQL语句的执行过程

    SQL语句在数据库中处理过程是怎样的呢?执行顺序呢?在回答这个问题前,我们先来回顾一下:在ORACLE数据库系统架构下,SQL语句由用户进程产生,然后传到相对应的服务端进程,之后由服务器进程执行该SQ ...

  7. 官方文档:11G新特性SQL PLAN BASLINE 执行计划基线

    什么是SQL执行计划管理? SQL计划管理(SQL plan management)是一咱预防机制,记录和评估SQL语句的执行计划.SQL plan management的主要功能是sql plan ...

  8. 详细分析SQL语句逻辑执行过程和相关语法

    本文目录: 1.SQL语句的逻辑处理顺序 1.2 各数据库系统的语句逻辑处理顺序 1.2.1 SQL Server和Oracle的逻辑执行顺序 1.2.2 MariaDB的逻辑执行顺序 1.2.3 M ...

  9. mybatis下使用log4j打印sql语句和执行结果

    转载自:https://www.cnblogs.com/jeevan/p/3493972.html 本来以为很简单的问题, 结果自己搞了半天还是不行; 然后google, baidu, 搜出来各种方法 ...

随机推荐

  1. web容器调用Filter和Servlet顺序学习

    web容器调用Filter和Servlet顺序学习    一直对Filter和Servlet在哪里被web容器调用迷惑,后查看tomcat源码,揭开了其面纱.1. 下面是一个简单的时序图: 2. 对上 ...

  2. rpm卸载软件error preun

    这两天,使用ipvsadm -ln总是显示空. 后来,使用strace ipvsadm -ln定位 看来,是ipvsadm模块有问题,卸载了再重新安装吧,结果出现这种问题. 从来没遇到这种问题: er ...

  3. DATEDIFF 的用法

    DECLARE @date DATETIME = '2017-12-26 00:00:00';DECLARE @date2 DATETIME = DATEADD(DAY, 1, @date);DECL ...

  4. BZOJ2878 [Noi2012]迷失游乐园

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. review13

    Date与Calendar类 Date类和Calendar类属于java.util包. Date类 1.使用无参数构造方法 使用Date类的无参构造方法创建的对象可以获取本机的当前日期和时间,例如: ...

  6. 解决CentOS 6环境时区、日期、时间同步方法

    有些时候我们在选择的VPS服务商提供的VPS主机方案安装系统.安装建站环境之后就直接上马网站,但是我们会有发现发布的文章或者有些时候设置的自动执行脚本时间与我们实际的时间不符合.甚至有些程序是需要与本 ...

  7. zoj 3965 Binary Tree Restoring(搜索)

    Binary Tree Restoring Time Limit: 1 Second      Memory Limit: 65536 KB      Special Judge Given two ...

  8. IDEA配置JavaWeb项目Artifacts

  9. 《Effective C++》——条款04:确定对象使用前已先被初始化

    读取未初始化的值会导致不明确的行为.在某些平台上,仅仅只是读取未初始化的值,就可能让你的程序终止运行.更可能的情况是读入一些“半随机”bits,污染了正在进行读取动作的那个对象,最终导致不可预知的程序 ...

  10. java学习笔记 --- 多线程(多线程的创建方式)

    1.创建多线程方式1——继承Thread类. 步骤:  A:自定义类MyThread继承Thread类.  B:MyThread类里面重写run()? 为什么是run()方法呢? C:创建对象 D:启 ...