Oracle 12CR2查询转换教程之cursor-duration临时表详解

 更新时间:2018年11月01日 10:08:05   作者:jydba  
这篇文章主要给大家介绍了关于Oracle 12CR2查询转换教程之cursor-duration临时表的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在Oracle12C中为了物化查询的中间结果,Oracle数据库在查询编译时在内存中可能会隐式的创建一个cursor_duration临时表。

下面话不多说了,来一起看看详细的介绍吧

Cursor-Duration临时表的作用

复杂查询有时会处理相同查询块多次,这将会增加不必要的性能开锁。为了避免这种问题,Oracle数据库可以在游标生命周期内为查询结果创建临时表并存储在内存中。对于有with子句查询,星型转换与分组集合操作的复杂操作,这种优化增强了使用物化中间结果来优化子查询。在这种方式下,cursor-duration临时表提高了性能并且优化了I/O。

Cursor-Duration临时表工作原理

cursor-definition临时表定义内置在内存中。表定义与游标相关,并且只对执行游标的会话可见。当使用cursor-duration临时表时,数据库将执行以下操作:

1.选择使用cursor-duration临时表的执行计划

2.创建临时表时使用唯一名

3.重写查询引用临时表

4.加载数据到内存中直到没有内存可用,在这种情次品下将在磁盘上创建临时段

5.执行查询,从临时表中返回数据

6.truncate表,释放内存与任何磁盘上的临时段

注意,cursor-duration临时表的元数据只要cursor在内存中就会一直存在于内存中。元数据不会存储在数据字典中这意味着通过数据字典视图将不能查询到,不能显性地删除元数据。上面的场景依赖于可用的内存。对于特定查询,临时表使用PGA内存。

cursor-duration临时表的实现类似于排序。如果没有可用内存,那么数据库将把数据写入临时段。对于cursor-duration临时表,主要差异如下:

.在查询结束时数据库释放内存与临时段而不是当row source不现活动时释放。

.内存中的数据仍然存储在内存中,不像排序数据可能在内存与临时段之间移动。

当数据库使用cursor-duration临时表时,关键字cursor duration memory会出现在执行计划中。

cursor-duration临时表使用场景

一个with查询重复相同子查询多次可能有时使用cursor-duration临时表性能更高,下面的查询使用一个with子句来创建三个子查询块:

SQL> set long 99999
SQL> set linesize 300
SQL> with
 2 q1 as (select department_id, sum(salary) sum_sal from hr.employees group by
 3 department_id),
 4 q2 as (select * from q1),
 5 q3 as (select department_id, sum_sal from q1)
 6 select * from q1
 7 union all
 8 select * from q2
 9 union all
 10 select * from q3;

DEPARTMENT_ID SUM_SAL
------------- ----------
   100  51608
   30  24900
     7000
   90  58000
   20  19000
   70  10000
   110  20308
   50  156400
   80  304500
   40  6500
   60  28800
   10  4400
   100  51608
   30  24900
     7000
   90  58000
   20  19000
   70  10000
   110  20308
   50  156400
   80  304500
   40  6500
   60  28800
   10  4400
   100  51608
   30  24900
     7000
   90  58000
   20  19000
   70  10000
   110  20308
   50  156400
   80  304500
   40  6500
   60  28800
   10  4400

36 rows selected.

下面是优化转换后的执行计划

SQL> select * from table(dbms_xplan.display_cursor(format=>'basic +rows +cost'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
with q1 as (select department_id, sum(salary) sum_sal from hr.employees
group by department_id), q2 as (select * from q1), q3 as (select
department_id, sum_sal from q1) select * from q1 union all select *
from q2 union all select * from q3

Plan hash value: 4087957524

----------------------------------------------------------------------------------------------------
| Id | Operation        | Name      | Rows | Cost (%CPU)|

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT       |       |  |  6 (100)|
| 1 | TEMP TABLE TRANSFORMATION    |       |  |   |
| 2 | LOAD AS SELECT (CURSOR DURATION MEMORY)| SYS_TEMP_0FD9E08D2_620789C |  |   |
| 3 | HASH GROUP BY       |       | 11 | 276 (2)|
| 4 |  TABLE ACCESS FULL     | EMPLOYEES     | 100K| 273 (1)|
| 5 | UNION-ALL        |       |  |   |
| 6 | VIEW         |       | 11 |  2 (0)|
| 7 |  TABLE ACCESS FULL     | SYS_TEMP_0FD9E08D2_620789C | 11 |  2 (0)|
| 8 | VIEW         |       | 11 |  2 (0)|
| 9 |  TABLE ACCESS FULL     | SYS_TEMP_0FD9E08D2_620789C | 11 |  2 (0)|
| 10 | VIEW         |       | 11 |  2 (0)|
| 11 |  TABLE ACCESS FULL     | SYS_TEMP_0FD9E08D2_620789C | 11 |  2 (0)|
----------------------------------------------------------------------------------------------------


26 rows selected.

在上面的执行计划中,在步骤1中的TEMP TABLE TRANSFORMATION指示数据库使用cursor-duration临时表来执行查询。在步骤2中的CURSOR DURATION MEMORY指示数据库使用内存,如果有可用内存,将结果作为临时表SYS_TEMP_0FD9E08D2_620789C来进行存储。如果没有可用内存,那么数据库将临时数据写入磁盘。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • Oracle 存储过程教程

    Oracle 存储过程教程

    一个简单的oracle分页存储过程的实现和调用。在看了众多的分页存储过程以后发现都是针对sqlserver的,而没有oracle的,因此想写一个关于oracle的存储过程,因为我用到的数据库是oracle。
    2009-10-10
  • Oracle中的instr()函数应用及使用详解

    Oracle中的instr()函数应用及使用详解

    这篇文章主要介绍了Oracle中的instr()函数应用及使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • oracle获取当前时间,精确到毫秒并指定精确位数的实现方法

    oracle获取当前时间,精确到毫秒并指定精确位数的实现方法

    下面小编就为大家带来一篇oracle获取当前时间,精确到毫秒并指定精确位数的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • oracle中distinct的用法详解

    oracle中distinct的用法详解

    distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。
    2015-09-09
  • oracle 函数判断字符串是否包含图片格式的实例代码

    oracle 函数判断字符串是否包含图片格式的实例代码

    本文通过实例代码给大家介绍了oracle 函数判断字符串是否包含图片格式的相关资料,需要的朋友可以参考下
    2017-07-07
  • ORACLE常见错误代码的分析与解决(三)

    ORACLE常见错误代码的分析与解决(三)

    ORACLE常见错误代码的分析与解决(三)...
    2007-03-03
  • Oracle 临时表空间SQL语句的实现

    Oracle 临时表空间SQL语句的实现

    临时表空间用来管理数据库排序操作以及用于存储临时表、中间排序结果等临时对象,本文主要介绍了Oracle 临时表空间SQL语句的实现,感兴趣的可以了解一下
    2021-09-09
  • oracle11g 最终版本11.2.0.4安装详细过程介绍

    oracle11g 最终版本11.2.0.4安装详细过程介绍

    这篇文章主要介绍了oracle11g 最终版本11.2.0.4安装详细过程介绍,详细的介绍了每个安装步骤,有兴趣的可以了解一下。
    2017-03-03
  • Oracle 数据库连接查询SQL语句

    Oracle 数据库连接查询SQL语句

    oracle 连接查询分如下几种方法,大家可以看看,整理了下oracle 内外链接。
    2009-08-08
  • Oracle 数据显示 横表转纵表

    Oracle 数据显示 横表转纵表

    横表转纵表亦可用与decode意义相似的case语句实现,原理同该语句,这里不再过多描述。
    2009-07-07

最新评论