SQL plan directives

SQL plan directives含有优化器产生优化的执行计划时需要的附加信息和指令。 在sql执行时,如果cardinality估计有错误,数据库就会创建sql plan directives。编译sql时,优化器会检测查询对应的directive,确认sql plan directives中是否包含额外的统计信息。

如果sql plan directive中没有相关的统计信息,优化器会使用动态统计信息。比如,没有创建列组统计信息(column group statistics)时,优化器收集使用动态统计信息。目前优化器只能监控列组的动态统计信息,不能对表达式。

SQL plan directive不是和某个指定的sql语句或者sql_id相关联。优化器可以对类似的sql使用相同的sql plan directive。因为SQL plan directive不是以sql语句为单位,而是以表达式为单位,这也就意味着优化器可以对多个不同的sql应用相同的SQL plan directive。

数据库自动管理sql plan directive。数据库一开始是在share pool中创建sql plan directive。并阶段性的把sql plan directive写到sysaux表空间中。默认情况下Oracle每15分钟会自动将内存中的SQL plan directive写入SYSAUX表空间,也可以通过DBMS_SPD包进行手动管理。

数据库使用SQL plan directive示例

$ sqlplus sh/sh@pdb2
SQL> drop table tab1 purge;
SQL> create table tab1(
2 id number,
3 gender varchar2(1),
4 has_y_chromosome varchar2(1),
5 constraint tab1_pk primary key(id),
6 constraint tab1_gender_chk check (gender in ('M','F')),
7 constraint tab1_has_y_chromosome_chk check (has_y_chromosome in ('Y','N'))
8 ); Table created. SQL> insert /*+ append */ into tab1
2 select level,'M','Y'
3 from dual
4 connect by level <= 10; 10 rows created. SQL> commit;
SQL> insert /*+ append */ into tab1
2 select 10+level,'F','N'
3 from dual
4 connect by level<=90; 90 rows created. SQL> commit;
SQL> create index tab1_gender_idx on tab1(gender);
SQL> create index tab1_has_y_chromosome_idx on tab1(has_y_chromosome);
SQL> exec dbms_stats.gather_table_stats(USER,'TAB1'); #此时没有任何直方图信息
SQL> select column_id,column_name,histogram
2 from user_tab_columns
3 where table_name='TAB1'
4 order by column_id; COLUMN_ID COLUMN_NAME HISTOGRAM
---------- -------------------- ---------------
1 ID NONE
2 GENDER NONE
3 HAS_Y_CHROMOSOME NONE SQL> 实际数据中,所有males都有Y标志,但是所有females都没有。不过优化器并不知道这点。
优化器会评估谓词的selectivity,假设数据是均衡分布的,两个列相互独立,认为25行数据既含male列又含有Y标记。
SQL> select /*+ gather_plan_statistics */ *
2 from tab1
3 where gender='M'
4 and has_y_chromosome='Y'; ID G H
---------- - -
1 M Y
2 M Y
3 M Y
4 M Y
5 M Y
6 M Y
7 M Y
8 M Y
9 M Y
10 M Y 10 rows selected. SQL> SELECT * FROM TABLE(DBMS_XPLAN.display_cursor(format => 'allstats last')); PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------
SQL_ID dnpgrp1fvkp7t, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ * from tab1 where gender='M' and has_y_chromosome='Y' Plan hash value: 1552452781 -----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 | 4 |
|* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB1 | 1 | 25 | 10 |00:00:00.01 | 4 |
|* 2 | INDEX RANGE SCAN | TAB1_GENDER_IDX | 1 | 50 | 10 |00:00:00.01 | 2 |
----------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("HAS_Y_CHROMOSOME"='Y')
2 - access("GENDER"='M') 21 rows selected. SQL>
如上结果所示,发生的cardinality 的估算错误。此时如果有直方图信息、或者扩展统计信息,优化器会评估出更准确的cardinality。 查看v$sql,确认该sql计划是否还可以优化。IS_REOPTIMIZABLE=Y表示优化器已经意识到cardinality估算不准,也表示SQL plan directives已经被创建:
SQL> select sql_text,is_reoptimizable
2 from v$sql
3 where sql_id='dnpgrp1fvkp7t'; SQL_TEXT IS_REOPTIMIZABLE
---------------------------------------- ----------------
select /*+ gather_plan_statistics */ * Y
from tab1 where gender='M' and has_y
_chromosome='Y' SQL> 查看sql plan directives
直线以下sql查看,如果查不到结果,说明sql plan directive还没有刷新到磁盘:
SQL> select to_char(d.directive_id) dir_id,o.owner,o.object_name,o.subobject_name col_name,o.object_type,d.type,d.state,d.reason
2 from dba_sql_plan_directives d,dba_sql_plan_dir_objects o
3 where d.directive_id=o.directive_id
4 and o.owner='SH'
5 order by 1,2,3,4,5; no rows selected SQL> 手动刷新
SQL> exec dbms_spd.flush_sql_plan_directive;
SQL> select to_char(d.directive_id) dir_id,o.owner,o.object_name,o.subobject_name col_name,o.object_type,d.type,d.state,d.reason
2 from dba_sql_plan_directives d,dba_sql_plan_dir_objects o
3 where d.directive_id=o.directive_id
4 and o.owner='SH'
5 order by 1,2,3,4,5; DIR_ID OWNER OBJECT_NAM COL_NAME OBJECT TYPE STATE REASON
-------------------- ---------- ---------- ---------- ------ ---------------- ---------- ------------------------------------
17805875575772415323 SH TAB1 GENDER COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
17805875575772415323 SH TAB1 TABLE DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE SQL> 再次执行查询,这次查询会使用到上面创建的sql plan directive_id SQL> select /*+ gather_plan_statistics */ *
2 from tab1
3 where gender='M'
4 and has_y_chromosome='Y'; ID G H
---------- - -
1 M Y
2 M Y
3 M Y
4 M Y
5 M Y
6 M Y
7 M Y
8 M Y
9 M Y
10 M Y 10 rows selected. SQL> SET LINESIZE 200 PAGESIZE 100
SQL> SELECT * FROM TABLE(DBMS_XPLAN.display_cursor(format => 'allstats last')); PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------
SQL_ID gj6qavway0k06, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ * from tab1 where gender='M' and has_y_chromosome='Y' Plan hash value: 1552452781 -----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 | 4 |
|* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB1 | 1 | 10 | 10 |00:00:00.01 | 4 |
|* 2 | INDEX RANGE SCAN | TAB1_GENDER_IDX | 1 | 10 | 10 |00:00:00.01 | 2 |
----------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("HAS_Y_CHROMOSOME"='Y')
2 - access("GENDER"='M') Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- 1 Sql Plan Directive used for this statement 26 rows selected. SQL>

SQL plan directives的更多相关文章

  1. [20181225]12CR2 SQL Plan Directives.txt

    [20181225]12CR2 SQL Plan Directives.txt --//12C引入SQL PLAN Directives.12cR1版本会造成大量的动态取样,影响性能.许多人把OPTI ...

  2. Oracle SQL操作计划基线总结(SQL Plan Baseline)

    一.基础概念 Oracle 11g開始,提供了一种新的固定运行计划的方法,即SQL plan baseline,中文名SQL运行计划基线(简称基线),能够觉得是OUTLINE(大纲)或者SQL PRO ...

  3. oracle11g中SQL优化(SQL TUNING)新特性之SQL Plan Management(SPM)

    1.   简介 Oracle Database11gR1引进了SQL PlanManagement(简称SPM),一套允许DBA捕获和保持任意SQL语句执行计划最优的新工具,这样,限制了刷新优化器统计 ...

  4. 11g新特性-SQL Plan Management

    在11g之前版本,提供了stored outlines(sql概要)特性来保存sql的执行计划. 在11g中,引入了一个新的特性sql计划管理(sql plan management)特性来保存sql ...

  5. 免費查看SQL PLAN的工具 - SQL Sentry Plan Explorer

    今天 Terry大 介紹給小弟這個 SQL Sentry Plan Explorer 工具,可以用來看SQL Plan. 什麼? 用SSMS看不就很清楚了嗎? 這個Tool有把SQL Plan幫我們整 ...

  6. Oracle 固定执行计划-使用SPM(Sql Plan Management)固定执行计划

    固定执行计划-使用SPM(Sql Plan Management)固定执行计划 转载自:http://www.lunar2013.com/2016/01/固定执行计划-使用spm%EF%BC%88sq ...

  7. 11g的新特性:SQL Plan Management(SPM)

    Oracle11g中,Oracle提供dbms_spm包来管理SQL Plan,SPM是一个预防机制,它记录并评估sql的执行计划,将已知的高效的sql执行计划建立为SQL Plan Baseline ...

  8. Oracle 11g 新特性 --SQL Plan Management 说明

    Oracle 11g 新特性 --SQL Plan Management 说明 参见大神博主文章: http://blog.csdn.net/tianlesoftware/article/detail ...

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

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

随机推荐

  1. 电子商务 B2C 结构图【转载+整理】

    本文内容 商品展示 内容展示 订单确认 支付系统 用户中心 商品&促销 CRM 订单处理 WMS 采购管理 财务管理 报表管理 系统设置 WA系统   商品展示 按照 Ebay 内部分类,任何 ...

  2. stingray前端架构总体设计及运行过程

    SPA 单页应用程序,在一个页面内用ajax技术实现所有的功能的web程序,我们称之为单页应用,明显的特点就是第一次加载之后地址栏非参数部分不再发生变化.大家观察会发现 WIP系统就是一个SPA.我们 ...

  3. 2016 博客导读总结 &amp; 个人感悟

    此文着笔之时.2017已经在眼前了.预计等我写完,2017已经到了. 二次编辑于2017年1月1日早11点. 关于2016的感悟.十二月初就想写,当时认为是有点太早了,只是却思绪如泉涌. 且那时候才刚 ...

  4. scons, cmake, bazel

    http://scons.org/doc/production/HTML/scons-user/index.html https://github.com/PaddlePaddle/Paddle/is ...

  5. HTML拾遗

    一:标签 1:强调 <strong>加醋.<em>斜体 2:单独样式 <span>如果不加样式,那它包围的文字就是普通文字,可以在span中增加样式,就所包围的内容 ...

  6. [nQSError: 37001]Could not connect to the Oracle BI Server Instance

    [nQSError: 37001]Could not connect to the Oracle BI Server Instance 使用本机的OBIEE Client 的Oracle BI管理工具 ...

  7. Xcode7安装CocoaPods

    一.CocoaPods介绍以及优点 CocoaPods 是开发 OS X 和 iOS 应用程序的一个第三方库的依赖管理工具.该项目源代码在Github上管理. 通过 CocoaPods,能够非常方便的 ...

  8. python模块之keyword

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python模块之keyword import keyword ''' >>> help( ...

  9. code vs 3492 细胞个数

    题目链接:http://codevs.cn/problem/3492/ 题目描述 Description 一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为 ...

  10. Quartz.NET开源作业调度框架系列(二):CronTrigger-转

    CronTriggers比SimpleTrigger更加的灵活和有用,对于比较复杂的任务触发规则,例如"每个星期天的晚上12:00"进行备份任务,SimpleTrigger就不能胜 ...