ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 三种建表方式有什么异同。

三种建表方式有什么异同。

原创 Linux操作系统 作者:wei-xh 时间:2010-06-27 16:08:13 0 删除 编辑

第一种:create table s as select * from dba_objects;
第二种:create table s as select * from dba_objects where 1=0;
        insert /*+ append */ into s select * from dba_objects;
第三种:create table s as select * from dba_objects where 1=0;
        insert into s select * from dba_objects;


第一种建表方式产生的REDO量是79648
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            644392

已用时间:  00: 00: 00.01
SQL> create table s as select * from dba_objects;

表已创建。

已用时间:  00: 00: 00.57
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            724040

已用时间:  00: 00: 00.00
SQL> select 724040-644392 from dual;

724040-644392
-------------
        79648


2)第二种建表产生的REDO量是18528+2304= 20832
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            502228

已用时间:  00: 00: 00.01
SQL> create table s as select * from dba_objects where 1=0;

表已创建。

已用时间:  00: 00: 00.11
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            520756

已用时间:  00: 00: 00.01
SQL> select 520756-502228 from dual;

520756-502228
-------------
        18528

已用时间:  00: 00: 00.01

SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            930940

已用时间:  00: 00: 00.01
SQL> insert /*+ append */ into s select * from dba_objects;

已创建49900行。

已用时间:  00: 00: 00.60
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            933244

已用时间:  00: 00: 00.01
SQL> select 933244-930940 from dual;

933244-930940
-------------
         2304

第三种建表产生的redo量是5658116
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';


NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                                 0

已用时间:  00: 00: 00.01
SQL> create table s as select * from dba_objects where 1=0;

表已创建。

已用时间:  00: 00: 00.22
SQL> insert into s select * from dba_objects;

已创建49900行。

已用时间:  00: 00: 00.62
SQL> select a.name,b.value from v$statname a,v$mystat b where a.statistic#=b.statistic# and a.name='redo size';


NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                           5658116

已用时间:  00: 00: 00.01





从实验结果看第二种建表方式产生的REDO两最少。第一种次之,第三种产生的日志量最多。
第二种采用直接路径插入,几乎不产生日志,理解。
第三种常规路径插入,产生日志,理解。
那第一种呢,后台不知道执行的是个什么操作?

 

从10046跟踪文件能够看出第一种与第二种的本质是一样的,都是采用的直接路径加载。每种方法测试前都先执行以下语句:
SQL> alter system flush buffer_cache;
用tkprof格式化跟踪文件,并按照响应时间排序,这里仅截取重要部分,其他部分略。
C:\>tkprof D:\oracle\product\10.2.0\admin\rose\udump\rose_ora_3752_wxh.trc D:\oracle\product\10.2.0\admin\rose\udump\wxh.log sort=prsela,exeela,fchela

第一种建表方式的跟踪文件输出:
create table s as select * from dba_objects


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.00          0          0          0           0
Execute      1      1.27       3.29        889       5213       1280       49900
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      1.28       3.30        889       5213       1280       49900

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  control file sequential read                    5        0.01          0.01
  db file sequential read                       282        0.06          0.83
  db file scattered read                         78        0.14          0.95
  direct path write                               5        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.00          0.00
*****************************************************************************

第二种建表方式跟踪文件输出:
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.05       0.04          0          0          0           0
Execute      1      1.39       2.99        890       5351       1253       49900
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      1.44       3.04        890       5351       1253       49900

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  control file sequential read                    5        0.01          0.05
  db file sequential read                       283        0.06          0.78
  db file scattered read                         78        0.06          0.72
  
direct path write                               5        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.00          0.00
*****************************************************************************

第三种建表方式跟踪文件输出:
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0          0          0           0
Execute      1      1.35       2.76        886       6273       6821       49900
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      1.37       2.78        886       6273       6821       49900
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                       282        0.11          0.75
  db file scattered read                         78        0.05          0.64
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.00          0.00
********************************************************************************

第一种与第二种建表方式统计信息部分、等待事件部分都几乎完全一样,特别需要注意两种建表方式都有一个'另我兴奋'的等待事件:direct path write,这个等待事件说明ORACLE直接从PGA写数据到数据文件或临时文件绕过了SGA。不过另我不惑的是第二种建表方式的跟踪文件里没有找到类似insert /*+ append */的递归语句。可能本来就不该有?

还可以通过autotrace辅助证明,create table ...as select ..。采取的是直接路径加载。

SQL> alter system flush buffer_cache;
系统已更改。
已用时间:  00: 00: 00.20
SQL> set autotrace on statistics
SQL> create table s as select * from dba_objects;
表已创建。
已用时间:  00: 00: 02.62
SQL> select count(*) from s;
  COUNT(*)
----------
     49900
已用时间:  00: 00: 00.57
统计信息
------------------------------------------------------
         28  recursive calls
          0  db block gets
        762  consistent gets
        686 physical reads
          0  redo size
        409  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
统计资料显示全是物理读取,说明ORACLE绕过了SGA,直接通过PGA来写数据文件了。

实验结论如下:
create table as select ..建表语句采用直接路径加载的方式进行,效果等同于先create table再采用直接路径insert。



[ 本帖最后由 wei-xh 于 2010-6-27 14:53 编辑 ]

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/22034023/viewspace-666440/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE组成员,DBGeeK用户组发起人。曾在DTCC、ORACLE技术嘉年华、Gdevops等公开场合做过数据库技术专题分享,2017年应Oracle邀请在世界最大的数据库会议OOW上做技术分享。组织翻译了《拨云见日,解密Oracle ASM内核》一书。

注册时间:2009-07-04

  • 博文量
    422
  • 访问量
    2425352