[20181108]with temp as 建立临时表吗.txt
[20181108]with temp as 建立临时表吗.txt
--//链接:http://www.itpub.net/thread-2106304-1-1.html
--//作者提到在dg上使用with查询的sql语句报错.出现如下错误:
ORA-00604: error occurred at recursive SQL level 2
ORA-16000: database open for read-only access
--//我在11.2.0.3以及11.2.0.4上使用dg都无法再现作者遇到的问题,不过里面提到要建立一个临时表.我跟踪看看.
1.环境:
SCOTT@book> @ ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
2.测试:
SCOTT@book> @ 10046on 12
old 1: alter session set events '10046 trace name context forever, level &1'
new 1: alter session set events '10046 trace name context forever, level 12'
Session altered.
SCOTT@book> with x1 as (select /*+ materialize */ deptno,sum(sal) from emp group by deptno) select * from x1;
DEPTNO SUM(SAL)
---------- ----------
30 9400
20 10875
10 8750
SCOTT@book> @ 10046off
Session altered.
SCOTT@book> @ pp
TRACEFILE
--------------------------------------------------------------
/u01/app/oracle/diag/rdbms/book/book/trace/book_ora_16666.trc
SCOTT@book> @ dpc b52t0afdmxyxf ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID b52t0afdmxyxf, child number 0
-------------------------------------
with x1 as (select /*+ materialize */ deptno,sum(sal) from emp group by
deptno) select * from x1
Plan hash value: 2072880957
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | Writes | OMem | 1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 6 (100)| | 3 |00:00:00.01 | 22 | 7 | 1 | | | |
| 1 | TEMP TABLE TRANSFORMATION | | 1 | | | | | 3 |00:00:00.01 | 22 | 7 | 1 | | | |
| 2 | LOAD AS SELECT | | 1 | | | | | 0 |00:00:00.01 | 10 | 6 | 1 | 270K| 270K| 270K (0)|
| 3 | HASH GROUP BY | | 1 | 3 | 21 | 4 (25)| 00:00:01 | 3 |00:00:00.01 | 6 | 6 | 0 | 1214K| 1214K| 1259K (0)|
| 4 | TABLE ACCESS FULL | EMP | 1 | 14 | 98 | 3 (0)| 00:00:01 | 14 |00:00:00.01 | 6 | 6 | 0 | | | |
| 5 | VIEW | | 1 | 3 | 78 | 2 (0)| 00:00:01 | 3 |00:00:00.01 | 6 | 1 | 0 | | | |
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6600_176524F2 | 1 | 3 | 21 | 2 (0)| 00:00:01 | 3 |00:00:00.01 | 6 | 1 | 0 | | | |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$2
2 - SEL$1
4 - SEL$1 / EMP@SEL$1
5 - SEL$D67CB2D2 / X1@SEL$2
6 - SEL$D67CB2D2 / T1@SEL$D67CB2D2
--//可以发现执行计划中出现一个表SYS_TEMP_0FD9D6600_176524F2.
3.检查跟踪文件发现如下:
=====================
PARSING IN CURSOR #140363556544784 len=177 dep=1 uid=0 oct=1 lid=0 tim=1541638752385719 hv=3738467917 ad='7be14610' sqlid='5j608hvgd8zkd'
CREATE GLOBAL TEMPORARY T
~~~~~~~~~~~~~~~~~~~~~~~~~
END OF STMT
PARSE #140363556544784:c=1000,e=693,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1541638752385717
BINDS #140363556569464:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=80 off=0
kxsbbbfp=7fa8efe44fc0 bln=22 avl=02 flg=05
value=1
Bind#1
oacdty=01 mxl=32(27) mxlc=00 mal=00 scl=00 pre=00
oacflg=10 fl2=0001 frm=01 csi=852 siz=0 off=24
kxsbbbfp=7fa8efe44fd8 bln=32 avl=27 flg=01
value="SYS_TEMP_0FD9D6600_176524F2"
Bind#2
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=0 off=56
kxsbbbfp=7fa8efe44ff8 bln=22 avl=02 flg=01
value=1
EXEC #140363556569464:c=0,e=200,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=4,plh=2853959010,tim=1541638752386116
FETCH #140363556569464:c=0,e=19,p=0,cr=3,cu=0,mis=0,r=0,dep=2,og=4,plh=2853959010,tim=1541638752386157
CLOSE #140363556569464:c=0,e=2,dep=2,type=3,tim=1541638752386194
=====================
--//注意看下划下显示信息不全,11.2.0.4都无法完整显示建表语句.这样看上去建立一个临时表的信息.
SCOTT@book> @ /desc sys.SYS_TEMP_0FD9D6600_176524F2
Name Null? Type
------------------------------- -------- ----------------------------
C0 NUMBER(2)
C1 NUMBER
--//查询可以发现该表名,实际上如果你刷新共享池后下次执行,可以发现这个临时表名会发生变化,我不做这测试,大家可以自行验证.
4.进一步验证:
--//链接提到:http://www.itpub.net/thread-2106304-1-1.html
*** 2018-11-06 17:45:04.545
KQRCMT: Write failed with error=604 po=00000006E229E0C8 cid=8
diagnostics : cid=8 hash=3374ad43 flag=2a
ORA-00604: error occurred at recursive SQL level 2
ORA-16000: database open for read-only access
CREATE GLOBAL TEMPORARY TABLE "SYS"."SYS_TEMP_0FD9D6837_3AF8797C" ("C0" CHARACTER(36),"C1" NUMBER,"C2" DATE,"C3"
NUMBER,"C4" DATE ) IN_MEMORY_METADATA CURSOR_SPECIFIC_SEGMENT STORAGE (OBJNO 4254951479 ) NOPARALLEL
----- Current SQL Statement for this session (sql_id=avk2qrjwhx4zb) -----
--//可以看到类似建立临时表的语句.注意后面的参数IN_MEMORY_METADATA CURSOR_SPECIFIC_SEGMENT ,如果那这个语句在sql无法正常执
--//行的.
5.如果类似语句在12c下执行呢?
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0 12.2.0.1.0 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
SCOTT@test01p> with x1 as (select /*+ materialize */ deptno,sum(sal) from emp group by deptno) select * from x1;
DEPTNO SUM(SAL)
---------- ----------
30 9400
20 10875
10 8750
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID b52t0afdmxyxf, child number 0
-------------------------------------
with x1 as (select /*+ materialize */ deptno,sum(sal) from emp group by
deptno) select * from x1
Plan hash value: 2072880957
--------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 6 (100)| | | | |
| 1 | TEMP TABLE TRANSFORMATION | | | | | | | | |
| 2 | LOAD AS SELECT (CURSOR DURATION MEMORY)| SYS_TEMP_0FD9D660A_174F61 | | | | | 1024 | 1024 | |
| 3 | HASH GROUP BY | | 3 | 21 | 4 (25)| 00:00:01 | 1214K| 1214K| 1255K (0)|
| 4 | TABLE ACCESS FULL | EMP | 14 | 98 | 3 (0)| 00:00:01 | | | |
| 5 | VIEW | | 3 | 78 | 2 (0)| 00:00:01 | | | |
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D660A_174F61 | 3 | 21 | 2 (0)| 00:00:01 | | | |
--------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$2
2 - SEL$1
4 - SEL$1 / EMP@SEL$1
5 - SEL$D67CB2D2 / X1@SEL$2
6 - SEL$D67CB2D2 / T1@SEL$D67CB2D2
--//注意看id=2.Operation=LOAD AS SELECT (CURSOR DURATION MEMORY),id=1有1个操作TEMP TABLE TRANSFORMATION,我的理解转换为临
--//时表.也就是12c表示更加明确一些.刷新共享池后,使用10046 跟踪看看.
SCOTT@test01p> alter system flush shared_pool ;
System altered.
SCOTT@test01p> @ 10046on 12
Session altered.
SCOTT@test01p> with x1 as (select /*+ materialize */ deptno,sum(sal) from emp group by deptno) select * from x1;
DEPTNO SUM(SAL)
---------- ----------
30 9400
20 10875
10 8750
SCOTT@test01p> @ 10046off
Session altered.
--//检查跟踪文件,可以发现如下:
=====================
PARSING IN CURSOR #698582680 len=189 dep=1 uid=0 oct=1 lid=0 tim=2928951715 hv=3568969204 ad='7ff0a173d50' sqlid='6d7zw7rabn9gn'
CREATE GLOBAL TEMPORARY TABLE "SYS"."SYS_TEMP_0FD9D660B_174F61" SHARING=NONE ("C0" NUMBER(2),"C1" NUMBER )
IN_MEMORY_METADATA CURSOR_SPECIFIC_SEGMENT STORAGE (OBJNO 4254950923 ) NOPARALLEL
--//12c能完整显示建表语句.
END OF STMT
PARSE #698582680:c=0,e=4795,p=0,cr=48,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=2928951714
BINDS #698686824:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=1000001 frm=00 csi=00 siz=80 off=0
kxsbbbfp=2a461ab8 bln=22 avl=02 flg=05
value=1
Bind#1
oacdty=01 mxl=32(25) mxlc=00 mal=00 scl=00 pre=00
oacflg=10 fl2=0001 frm=01 csi=852 siz=0 off=24
kxsbbbfp=2a461ad0 bln=32 avl=25 flg=01
value="SYS_TEMP_0FD9D660B_174F61"
Bind#2
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=1000001 frm=00 csi=00 siz=0 off=56
kxsbbbfp=2a461af0 bln=22 avl=02 flg=01
value=1
EXEC #698686824:c=15600,e=249,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=4,plh=813480514,tim=2928952150
FETCH #698686824:c=0,e=11,p=0,cr=3,cu=0,mis=0,r=0,dep=2,og=4,plh=813480514,tim=2928952186
CLOSE #698686824:c=0,e=1,dep=2,type=3,tim=2928952220
BINDS #698742424:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=1000001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=2a461af0 bln=22 avl=06 flg=05
value=4254950923
EXEC #698742424:c=0,e=118,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=4,plh=1072382624,tim=2928952385
FETCH #698742424:c=0,e=8,p=0,cr=2,cu=0,mis=0,r=0,dep=2,og=4,plh=1072382624,tim=2928952419
CLOSE #698742424:c=0,e=1,dep=2,type=3,tim=2928952454
=====================
--//从语法看建立的不上临时表,或者仅仅是一种特殊的临时表.我查询一下,发现如下链接:
http://www.jydba.net/oracle-12cr2%e6%9f%a5%e8%af%a2%e8%bd%ac%e6%8d%a2%e4%b9%8bcursor-duration%e4%b8%b4%e6%97%b6%e8%a1%a8/
Oracle 12CR2查询转换之cursor-duration临时表
在Oracle12C中为了物化查询的中间结果,Oracle数据库在查询编译时在内存中可能会隐式的创建一个cursor_duration临时表。
--//这种临时表叫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会出现在执行计划中。
[20181108]with temp as 建立临时表吗.txt的更多相关文章
- [20190510]快速建立执行脚本.txt
[20190510]快速建立执行脚本.txt --//上午在测试建立表空间备份时,浪费一点点时间.脚本如下:$ cat d10.sqldrop tablespace t01 including con ...
- MacOS在Finder中建立快速新建txt的workflow
Mac是不支持右键直接新建txt的,因此有时候需要用到文本文稿的时候会比较麻烦. 因此这里提供一种个人认为比较方便的方法,让Mac也能很简洁的新建txt文件. 工具介绍: Automator ...
- SQL 建立临时表进行查询
SELECT min (maxrank) as minofmaxrank FROM (SELECT max(rank) as maxrank FROM tbl_core_staff WHERE st_ ...
- Oracle 临时表空间 temp表空间切换
一.TEMP表空间 临时表空间主要用途是在数据库进行排序运算.管理索引.访问视图等操作时提供临时的运算空间,当运算完成之后系统会自动清理.当oracle里需要用到sort的时候,PGA中sort_ar ...
- [20180918]文件格式与sql_id.txt
[20180918]文件格式与sql_id.txt --//记录测试中遇到的一个问题.这是我在探究SQL*Net more data from client遇到的问题.--//就是实际oracle会把 ...
- [20180327]行迁移与ITL浪费.txt
[20180327]行迁移与ITL浪费.txt --//生产系统遇到的一个问题,增加一个字段到表结构,修改数据字典,导致出现行迁移,而更加严重的是没有修改pctfree值,--//以后的业务操作,依旧 ...
- SQL数据库中临时表、临时变量和WITH AS关键词创建“临时表”的区别
原文链接:https://www.cnblogs.com/zhaowei303/articles/4204805.html SQL数据库中数据处理时,有时候需要建立临时表,将查询后的结果集放到临时表中 ...
- SQL Server临时表的使用方案
文章来源:http://www.codesky.net/article/201007/145241.html 我们今天是要和大家一起讨论的是SQL Server临时表的实用大全,如果你对SQL S ...
- SqlServer数据库优化之索引、临时表
问题:工作是查询一张500万多条数据的表时,查询总是很慢,于是进行优化. --查询表所有索引 use RYTreasureDB EXEC Sp_helpindex [RecordDrawScore] ...
随机推荐
- Android主线程的消息系统(Handler\Looper)
前言: 之前的文章写的都是关于Bitmap和内存的优化技术,这一篇文章给大家谈谈Handler. Handler是Android系统中比较重要的一个知识,在Android多线程面试经常会被问到,在实际 ...
- 一个前端开发者换电脑的过程(node & 淘宝镜像篇)
当然,在我们安装了git和vscode之后,我们这个项目,在本地仍然是跑不起来的对吗?这句“npm run dev”就提示着我们需要有一个npm,npm是一个很强大的包管理工具,就像是安卓的应用商店, ...
- SpringContextHolder 静态持有SpringContext的引用
import java.util.Map; import org.springframework.context.ApplicationContext; import org.springframew ...
- web认证
前言: HTTP是无状态协议,之前已认证成功的用户状态无法通过协议层面保存下来.即无法实现状态管理,我们使用Cookie来管理Session(会话),以弥补HTTP协议中不存在的状态管理功能. 步骤: ...
- linux下umask的使用讲解
最近开始学习linux ,看完马哥的linux课程关于umask的这个部分, 写这篇博客希望加深下我对umask的理解 和对umask不太清楚的博友一些帮助. 1 umask 是什么 当我们登录系统之 ...
- MFC控件GDI编程
MFC控件GDI编程 一丶学习内容 1.了解常用的GDI函数绘图. 2.使用常用的画笔画刷. 二丶常用的GDI函数绘图 上方则为我们常用的GDI函数了. 画线 矩形. 以及圆 等等. 2.1 画线代码 ...
- Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目
以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...
- Docker的基本操作与示例
一.RunC RunC是一个由OCI(Open Container Initiative)制定的标准化轻量容器运行工具.OCI是专门致力于制定容器格式和运行时开放的工业化标准的组织.那容器标准化后Do ...
- OJ:访问 const 成员函数问题
Description 补足程序使得其输出结果是: 40 #include <iostream> #include <string> using namespace std; ...
- HTML+CSS基础(1)-理解什么是HTML和CSS
什么是HTML w3c的解释如下: HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种 ...