• 创建测试表

  1. 以用户jyu连接,创建测试表
  2. SQL> conn jyu/jyu;
  3. Connected.
  4.  
  5. SQL> create table t (id number, name varchar2(100));
  6.  
  7. Table created.
  8.  
  9. SQL> insert into t select rownum,object_name from dba_objects;
  10.  
  11. 47391 rows created.
  12.  
  13. SQL> commit;
  14.  
  15. Commit complete.
  16.  
  17. 创建索引
  18. SQL> create index t_idx1 on t(id);
  19.  
  20. Index created.
  21.  
  22. 收集统计数据
  23. SQL> exec dbms_stats.gather_table_stats('JYU','T');
  24.  
  25. PL/SQL procedure successfully completed.
  • 执行计划

  1. 查看SQL语句执行计划
  2. SQL> set autotrace traceonly
  3. SQL> select * from t where id=1;
  4.  
  5. Execution Plan
  6. ----------------------------------------------------------
  7. Plan hash value: 3292636276
  8.  
  9. --------------------------------------------------------------------------------------
  10. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  11. --------------------------------------------------------------------------------------
  12. | 0 | SELECT STATEMENT | | 1 | 28 | 2 (0)| 00:00:01 |
  13. | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 28 | 2 (0)| 00:00:01 |
  14. |* 2 | INDEX RANGE SCAN | T_IDX1 | 1 | | 1 (0)| 00:00:01 |
  15. --------------------------------------------------------------------------------------
  16.  
  17. Predicate Information (identified by operation id):
  18. ---------------------------------------------------
  19.  
  20. 2 - access("ID"=1)
  21.  
  22. Note
  23. -----
  24. - outline "OLD_OUTLN" used for this statement
  25.  
  26. Statistics
  27. ----------------------------------------------------------
  28. 0 recursive calls
  29. 0 db block gets
  30. 4 consistent gets
  31. 0 physical reads
  32. 0 redo size
  33. 576 bytes sent via SQL*Net to client
  34. 492 bytes received via SQL*Net from client
  35. 2 SQL*Net roundtrips to/from client
  36. 0 sorts (memory)
  37. 0 sorts (disk)
  38. 1 rows processed
  39. SQL语句选择了使用索引的执行计划
  40.  
  41. 使用Hint指定语句使用全表扫描的执行计划
  42. SQL> explain plan for select /*+ full(t) */ * from t where id=1;
  43.  
  44. Explained.
  45.  
  46. SQL> select * from table(dbms_xplan.display);
  47.  
  48. PLAN_TABLE_OUTPUT
  49. ------------------------------------------------------------------------------------------------------------------------
  50. Plan hash value: 2153619298
  51.  
  52. --------------------------------------------------------------------------
  53. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  54. --------------------------------------------------------------------------
  55. | 0 | SELECT STATEMENT | | 1 | 28 | 50 (2)| 00:00:01 |
  56. |* 1 | TABLE ACCESS FULL| T | 1 | 28 | 50 (2)| 00:00:01 |
  57. --------------------------------------------------------------------------
  58.  
  59. Predicate Information (identified by operation id):
  60. ---------------------------------------------------
  61.  
  62. PLAN_TABLE_OUTPUT
  63. ------------------------------------------------------------------------------------------------------------------------
  64.  
  65. 1 - filter("ID"=1)
  66.  
  67. 13 rows selected.

使用outline固定执行计划

  1. sysdba连接数据库
  2. SQL> conn /as sysdba
  3. Connected.
  4.  
  5. 分别为2SQL语句创建outline
  6. SQL> alter session set current_schema = jyu;
  7.  
  8. Session altered.
  9.  
  10. SQL> create or replace outline OLD_OUTLN for category TEMP_PLAN on select * from t where id=1;
  11.  
  12. Outline created.
  13.  
  14. SQL> create or replace outline NEW_OUTLN for category TEMP_PLAN on select /*+ full(t) */ * from t where id=1;
  15.  
  16. Outline created.
  17.  
  18. 交换SQL语句的outline
  19. SQL> create private outline OLFROM from OLD_OUTLN;
  20.  
  21. Outline created.
  22.  
  23. SQL> create private outline OLTO from NEW_OUTLN;
  24.  
  25. Outline created.
  26.  
  27. SQL> update ol$ set hintcount=(select hintcount from ol$ where ol_name='OLTO') where ol_name='OLFROM';
  28.  
  29. 1 row updated.
  30.  
  31. SQL> delete from ol$ where ol_name='OLTO';
  32.  
  33. 1 row deleted.
  34.  
  35. SQL> update ol$ set ol_name='OLTO' where ol_name='OLFROM';
  36.  
  37. 1 row updated.
  38.  
  39. SQL> commit;
  40.  
  41. Commit complete.
  42.  
  43. SQL> execute dbms_outln_edit.refresh_private_outline('OLTO');
  44.  
  45. PL/SQL procedure successfully completed.
  46.  
  47. SQL> create or replace outline OLD_OUTLN from private OLTO for category GOOD_PLAN;
  48.  
  49. Outline created.
  50.  
  51. SQL> drop outline NEW_OUTLN;
  52.  
  53. Outline dropped.

  • 设置使用指定的outlines

  1. 有两种方式可在全局设置使用outline
  2.  
  3. 方式一:使用alter system设置(数据库重启后失效)
  4. SQL> conn / as sysdba
  5. Connected.
  6. SQL> alter system set use_stored_outlines=GOOD_PLAN;
  7.  
  8. System altered.
  9.  
  10. 方式二:通过trigger设置(数据库重启仍然有效)
  11. SQL> create or replace trigger enable_outlines_trig
  12. --Ref : How to Enable USE_STORED_OUTLINES Permanently (Doc ID 560331.1)
  13. after startup on database
  14. begin
  15. execute immediate('alter system set use_stored_outlines=GOOD_PLAN');
  16. end;
  17. /
  • 检查SQL语句执行计划

  1. SQL> conn jyu/jyu
  2. Connected.
  3. SQL> set autotrace traceonly
  4. SQL> select * from t where id=1;
  5.  
  6. Execution Plan
  7. ----------------------------------------------------------
  8. Plan hash value: 2153619298
  9.  
  10. --------------------------------------------------------------------------
  11. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  12. --------------------------------------------------------------------------
  13. | 0 | SELECT STATEMENT | | 1 | 28 | 50 (2)| 00:00:01 |
  14. |* 1 | TABLE ACCESS FULL| T | 1 | 28 | 50 (2)| 00:00:01 |
  15. --------------------------------------------------------------------------
  16.  
  17. Predicate Information (identified by operation id):
  18. ---------------------------------------------------
  19.  
  20. 1 - filter("ID"=1)
  21.  
  22. Note
  23. -----
  24. - outline "OLD_OUTLN" used for this statement
  25.  
  26. Statistics
  27. ----------------------------------------------------------
  28. 34 recursive calls
  29. 145 db block gets
  30. 269 consistent gets
  31. 0 physical reads
  32. 576 redo size
  33. 576 bytes sent via SQL*Net to client
  34. 492 bytes received via SQL*Net from client
  35. 2 SQL*Net roundtrips to/from client
  36. 2 sorts (memory)
  37. 0 sorts (disk)
  38. 1 rows processed

outline生效,SQL语句执行了全表扫描。

  1. #!/bin/bash
  2.  
  3. if [ $# -lt 3 ]; then
  4. cat <<EOF
  5. Fix given SQL plan using given sql in file
  6. usage: fix_plan.sh <hash_value> <hinted_sql_file> <owner>
  7. examples: fix_plan.sh 716428968 good.sql ALEX
  8. EOF
  9. exit 1
  10. fi
  11.  
  12. HASH_VALUE=$1
  13. SQL_FILE=$2
  14. OL_OWNER=$3
  15.  
  16. echo "HASH_VALUE : $HASH_VALUE"
  17. echo "SQL_FILE : $SQL_FILE"
  18. echo "OL_OWNER : $OL_OWNER"
  19. echo ""
  20.  
  21. #Create outline by hash_value
  22. function create_ol_from_hashvalue {
  23. HASH_VALUE=$1
  24. OL_NAME=$2
  25. OL_OWNER=$3
  26.  
  27. #generate create outline sql
  28. #I didn't use dbms_outln.create_outline, because it cannot create given name outline
  29. # and there's no hash value in V$SQL and DBA_OUTLINES to associate the two
  30. # according to "How To Match a SQL Statement to a Stored Outline (Doc ID 743312.1)"
  31. sqlplus -S "/ as sysdba" > /tmp/tmp_$OL_NAME.sql <<EOF
  32. set feedback off
  33. set serveroutput on size unlimited
  34. declare
  35. v_sqltext varchar2(32000);
  36. begin
  37. --get sql text
  38. select dbms_lob.substr(SQL_FULLTEXT, 30000, 1 ) into v_sqltext from v\$sql where hash_value = $HASH_VALUE and rownum=1;
  39.  
  40. dbms_output.put_line('alter session set current_schema = $OL_OWNER;');
  41. v_sqltext := 'create or replace outline $OL_NAME for category TEMP_PLAN on ' || chr(10) || v_sqltext || chr(10) ||';';
  42. dbms_output.put_line(v_sqltext);
  43. dbms_output.put_line('exit;');
  44. end;
  45. /
  46. EOF
  47.  
  48. sqlplus -S "/ as sysdba" @/tmp/tmp_$OL_NAME.sql
  49. }
  50.  
  51. #Create outline from sql file
  52. function create_ol_from_sqlfile {
  53. SQL_FILE=$1
  54. OL_NAME=$2
  55. OL_OWNER=$3
  56.  
  57. #generate create outline sql
  58. cat > /tmp/tmp_$OL_NAME.sql <<EOF
  59. alter session set current_schema = $OL_OWNER;
  60. create or replace outline $OL_NAME for category TEMP_PLAN on
  61. `cat $SQL_FILE`
  62. exit;
  63. EOF
  64.  
  65. sqlplus -S "/ as sysdba" @/tmp/tmp_$OL_NAME.sql
  66.  
  67. }
  68.  
  69. #Exchange outlines, make GOOD_SQL plan to GOOD_PLAN category
  70. #Ref: How to Edit a Stored Outline to Use the Plan from Another Stored Outline (Doc ID 730062.1)
  71. function exchange_outline {
  72. OL1=$1
  73. OL2=$2
  74. OL_OWNER=$3
  75.  
  76. sqlplus -S "/ as sysdba" <<EOF
  77. set feedback off
  78. alter session set current_schema = $OL_OWNER;
  79. create private outline OLFROM from $OL1;
  80. create private outline OLTO from $OL2;
  81. update ol$ set hintcount=(select hintcount from ol$ where ol_name='OLTO') where ol_name='OLFROM';
  82. delete from ol$ where ol_name='OLTO';
  83. update ol$ set ol_name='OLTO' where ol_name='OLFROM';
  84. commit;
  85. execute dbms_outln_edit.refresh_private_outline('OLTO');
  86. create or replace outline $OL1 from private OLTO for category GOOD_PLAN;
  87. drop outline $OL2;
  88. exit;
  89. EOF
  90.  
  91. }
  92.  
  93. #display outline
  94. function display_outline {
  95. OL_NAME=$1
  96. OL_OWNER=$2
  97.  
  98. sqlplus -S "/ as sysdba" <<EOF
  99. set pagesize 1000 linesize 160
  100. set long 32000
  101. col hint format a55
  102. col join_pos format a45
  103. col owner format a12
  104. col name format a18
  105. col ts format a14
  106. col h format 999
  107. col category format a12
  108. col sql_text format a80
  109. col used format a6
  110.  
  111. select name, sql_text, category, used, to_char(TIMESTAMP, 'YY-mm-dd hh24:MI')
  112. from dba_outlines
  113. where name = '$OL_NAME' and OWNER = '$OL_OWNER';
  114.  
  115. select ol_name name, category, hint#, stage# stage, hint_text hint, join_pred join_pos
  116. from outln.ol\$hints
  117. where ol_name = '$OL_NAME'
  118. order by ol_name, hint#;
  119. exit;
  120. EOF
  121. }
  122.  
  123. #main function
  124. echo "1. Create outline OL_$HASH_VALUE for SQL $HASH_VALUE"
  125. create_ol_from_hashvalue $HASH_VALUE OL_$HASH_VALUE $OL_OWNER
  126.  
  127. echo "2. Create outline OL_TEMP for SQL in $SQL_FILE"
  128. create_ol_from_sqlfile $SQL_FILE OL_TEMP $OL_OWNER
  129.  
  130. echo "3. Exchange outline OL_$HASH_VALUE with OL_TEMP, and drop OL_TEMP"
  131. exchange_outline OL_$HASH_VALUE OL_TEMP $OL_OWNER
  132.  
  133. echo "4. Display final outline for SQL $HASH_VALUE : OL_$HASH_VALUE in category GOOD_PLAN "
  134. 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. html div 加边框样式

    边框虚线样式:dashed边框实现样式:solid border:1px dashed #000代表设置对象边框宽度为1px黑色虚线边框 border:1px solid #000代表设置对象边框宽度 ...

  2. QT (QSS) 编程, QSS语法概述。。setstylesheet

    http://www.cnblogs.com/davesla/archive/2011/01/30/1947928.html 转载] QT皮肤(QSS)编程 借用css 的灵感, Qt也支持Qt自己的 ...

  3. Spring初学之bean的生命周期

    实体Bean: Car.java: package spring.beans.cycle; public class Car { private String name; private int pr ...

  4. ZigzagConvert

    public class ZigzagConvert { public static String convert(String s, int nRows) { int len = s.length( ...

  5. JMeter设置Http代理对web或者app进行录制

    一.录制web 1.首先保证JMeter的安装环境都正确.启动JMeter:在安装路径的bin目录下双击jmeter.bat (例如:D:\apache-jmeter-2.13\bin) ​2.打开J ...

  6. Linux 下安装 jdk-7u75-linux-x64.gz,jdk1.7.0_75,jdk1.7步骤:

    摘要:近来又用到了Linux系统,所以就又新装了一个虚拟机和CentOS 6.4来用,搞开发的程序猿们可能都知道,在现在的很多企业中,生产环境大多都是Linux服务器,并且用的比较多的大都是CentO ...

  7. 关于const_cast转换

    第一次看到const_cast转换,将const指针转换成普通的指针.很自然的想到:什么时候用const_cast?为什么要用它?这根const不是相互矛盾吗? (const_cast<ICef ...

  8. Jfinal整合百度富文本编辑器ueditor

    ueditor配置文件ueditor.config.js修改参数serverUrl:(改为要调用的action) 后台代码 package com.sandu.mega.admin.ueditor; ...

  9. AI探索(三)Tensorflow编程模型

    Tensorflow编程模型 ....后续完善 import os os.environ[' import numpy as np num_points = data_array = [] for i ...

  10. linux下安装Java se和Eclipse

    首先要去下载好JDK,Java SE 8的官方网址是http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213 ...