• 创建测试表

以用户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. centos7安装MPlyaer

    最近更换了centos7系统,对新系统的操作不是太熟悉.大神轻喷.昨晚突然想要下个电影看看,结果发现系统自带的播放器支持的视频格式有限,google查了一下,他们推荐使用MPlayer.于是经过一通g ...

  2. Python之爬虫总结

    一.爬虫之requests a.介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3)     b.注意:re ...

  3. jsp实现浏览器全屏

    在web系统中实现按钮控制浏览器全屏. <!DOCTYPE html> <%@ page contentType="text/html;charset=UTF-8" ...

  4. js+css实现简单下拉菜单

    <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312&qu ...

  5. STL迭代器辅助函数——advance

    Advance(i, n) increments the iterator i by the distance n. If n > it it , the call has no effect. ...

  6. VC6常用插件

    VC6常用插件 2009-10-09 17:27 1.Visual Assist(强烈推荐)    http://www.wholetomato.com/     VA从5.0一直到现在的VAX,功能 ...

  7. visual assist(VA)设置快捷键(其它安装的插件设置快捷键也在这里)

    安装完visual assist后发现快捷键无法使用纠结,然后找如何去设置快捷建以此记录一下: 在Tools-->customize-->Keyboard-->Add-ins 常用的 ...

  8. 机器学习(六)— logistic回归

    最近一直在看机器学习相关的算法,今天学习logistic回归,在对算法进行了简单分析编程实现之后,通过实例进行验证. 一 logistic概述 个人理解的回归就是发现变量之间的关系,也就是求回归系数, ...

  9. 性能测试工具BenchmarkDotnet

    .NET Core中的性能测试工具BenchmarkDotnet https://www.cnblogs.com/lwqlun/p/9671611.html 背景介绍 之前一篇博客中,我们讲解.NET ...

  10. Linux 链接网络

    目录 查看网卡 存在多个网卡 网卡配置静态IP 报错总结 诚邀访问我的个人博客:我在马路边 更好的阅读体验点击查看原文:Linux链接网络 原创博客,转载请注明出处 @ Linux在安装系统结束后总要 ...