如何通过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, 搜出来各种方法 ...
随机推荐
- html div 加边框样式
边框虚线样式:dashed边框实现样式:solid border:1px dashed #000代表设置对象边框宽度为1px黑色虚线边框 border:1px solid #000代表设置对象边框宽度 ...
- QT (QSS) 编程, QSS语法概述。。setstylesheet
http://www.cnblogs.com/davesla/archive/2011/01/30/1947928.html 转载] QT皮肤(QSS)编程 借用css 的灵感, Qt也支持Qt自己的 ...
- Spring初学之bean的生命周期
实体Bean: Car.java: package spring.beans.cycle; public class Car { private String name; private int pr ...
- ZigzagConvert
public class ZigzagConvert { public static String convert(String s, int nRows) { int len = s.length( ...
- JMeter设置Http代理对web或者app进行录制
一.录制web 1.首先保证JMeter的安装环境都正确.启动JMeter:在安装路径的bin目录下双击jmeter.bat (例如:D:\apache-jmeter-2.13\bin) 2.打开J ...
- Linux 下安装 jdk-7u75-linux-x64.gz,jdk1.7.0_75,jdk1.7步骤:
摘要:近来又用到了Linux系统,所以就又新装了一个虚拟机和CentOS 6.4来用,搞开发的程序猿们可能都知道,在现在的很多企业中,生产环境大多都是Linux服务器,并且用的比较多的大都是CentO ...
- 关于const_cast转换
第一次看到const_cast转换,将const指针转换成普通的指针.很自然的想到:什么时候用const_cast?为什么要用它?这根const不是相互矛盾吗? (const_cast<ICef ...
- Jfinal整合百度富文本编辑器ueditor
ueditor配置文件ueditor.config.js修改参数serverUrl:(改为要调用的action) 后台代码 package com.sandu.mega.admin.ueditor; ...
- AI探索(三)Tensorflow编程模型
Tensorflow编程模型 ....后续完善 import os os.environ[' import numpy as np num_points = data_array = [] for i ...
- linux下安装Java se和Eclipse
首先要去下载好JDK,Java SE 8的官方网址是http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213 ...