了解Maclean Liu|向Maclean Liu提问 Oracle ALLSTARS 全明星(群内有多位Oracle高级售后support,N位OCM和ACE) QQ群 # QQ群号:23549328 # 已经升级到 2000人群,空位多多。欢迎有一定基础的Oracle骨友加入,现在入群需要经过Maclean的技术面试,欢迎面试,请加QQ号:47079569 为好友参加面试 2群基础群 适合刚入门的同学,会共享最佳入门实践和资料 QQ群 # QQ群号:171092051 # 已经升级到 500人的超级群,空位多多,无需面试

CTAS VS create table and then insert

很多情况下我们都会需要复制源表数据以达到冗余数据的目的,那么到底是使用CREATE TABLE AS SELECT的CTAS方式,还是先建好表的结构然后再插入数据好呢? 我们来看看这2种方式的不同表现:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     1
Next log sequence to archive   2
Current log sequence           2

/* 数据库处于归档模式下 */

SQL> select ss.name,ms.value  from v$mystat ms,v$sysstat ss
  2  where
  3  ms.statistic#=ss.statistic#
  4  and ss.name in ('undo change vector size','redo size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                                 0
undo change vector size                                                   0

SQL> create table YOUYUS as select * from dba_objects;
Table created.

SQL> select ss.name,ms.value  from v$mystat ms,v$sysstat ss
  2  where
  3  ms.statistic#=ss.statistic#
  4  and ss.name in ('undo change vector size','redo size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                           5783384
undo change vector size                                               15408
/* CTAS方式产生了少量的undo,可以猜想其使用直接路径方式插入,Oracle仅产生维护数据字典的undo */

SQL> drop table YOUYUS;
Table dropped.

SQL> conn / as sysdba
Connected.

/* 清理现场 */

SQL> create table YOUYUS as select * from dba_objects where 0=1;
Table created.

SQL> select ss.name,ms.value  from v$mystat ms,v$sysstat ss
  2  where
  3  ms.statistic#=ss.statistic#
  4  and ss.name in ('undo change vector size','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                             19492
undo change vector size                                                5680

/* 建立空表YOUYUS,同样需要维护数据字典  */

SQL> insert into YOUYUS select * from dba_objects;

50729 rows created.

SQL> commit;

Commit complete.

SQL> select ss.name,ms.value  from v$mystat ms,v$sysstat ss
  2  where
  3  ms.statistic#=ss.statistic#
  4  and ss.name in ('undo change vector size','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                           5743540
undo change vector size                                              203904

/* 普通insert操作产生了远大于CTAS的undo */

SQL> drop table YOUYUS;
Table dropped.

SQL> conn / as sysdba
Connected.

SQL> select ss.name,ms.value  from v$mystat ms,v$sysstat ss
  2  where
  3  ms.statistic#=ss.statistic#
  4  and ss.name in ('undo change vector size','redo size');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                                 0
undo change vector size                                                   0


SQL> create table YOUYUS as select * from dba_objects where 0=1;
Table created.

SQL> insert /*+ append */ into YOUYUS select * from dba_objects;
50729 rows created.

SQL> commit;

Commit complete.

SQL> select ss.name,ms.value  from v$mystat ms,v$sysstat ss
  2  where
  3  ms.statistic#=ss.statistic#
  4  and ss.name in ('undo change vector size','redo size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                           5781712
undo change vector size                                               14808


/* 建表后直接路径插入方式与CTAS产生的redo和undo数量大致相仿 */
从资源消耗的角度讲CTAS或直接路径插入方式有一定优势,如果启用nologging选项的话这种优势会更加显著。

posted on 2010-09-07 20:12  Oracle和MySQL  阅读(273)  评论(0编辑  收藏  举报

导航