快速向表中插入大量数据Oracle中append与Nologging
来源于:http://blog.sina.com.cn/s/blog_61cd89f60102e7gi.html
当需要对一个非常大的表INSERT的时候,会消耗非常多的资源,因为update表的时候,oracle需要生成 redo log和undo log;此时最好的解决办法是用insert, 并且将表设置为nologging;当把表设为nologging后,并且使用的insert时,速度是最快的,这个时候oracle只会生成最低限度的必须的redo log,而没有一点undo信息。如果有可能将index也删除,重建
1.alter table table_name nologging;
2. insert into table_name select * from xxxx;
对此有了更好的解决方法:
1、alter table nologging;
注释:Nologging的设置跟数据库的运行模式有关
a、查询当前数据库的归档状态:
select name,log_mode from v$database;
默认为 NOARCHIVELOG 非归档
b、nologging在归档模式下有效,非归档模式nologging不起什么作用
c、为了提高插入的速度,我们可以对表关闭写log功能。 SQL 如下:
sql> alter table table_name NOLOGGING;
插入/修改,完数据后,再修改表写日志:
sql> alter table table_name LOGGING;
d、没有写log, 速度会块很多,但是也增加了风险,如果出现问题就不能恢复。
2、drop掉索引约束之类的;
注释:
3、
注释:
a. 、append 属于direct insert,归档模式下append+table nologging会大量减少日志,
非归档模式append会大量减少日志,append方式插入只会产生很少的undo
b、综合一下吧:一是减少对空间的搜索;二是有可能减少redolog的产生。所以append方式会快很多,一般用于大数据量的处理
c、建议不要经常使用append,这样表空间会一直在高水位上,除非你这个表只插不删
d、oracle append有什么作用?
请教一下,oracle中append是做什么用的。
insert into table1 select * from table2
在使用了append选项以后,insert数据会直接加到表的最后面,而不会在表的空闲块中插入数据。
使用append会增加数据插入的速度。
的作用是在表的高水位上分配空间,不再使用表的extent中的空余空间
append 属于direct insert,归档模式下append+table nologging会大量减少日志,
非归档模式append会大量减少日志,append方式插入只会产生很少的undo
不去寻找 freelist 中的free block , 直接在table HWM 上面加入数据。
4、总结
测试证明:
1. 不管哪种模式下append要与nologging方式联用才能达到很好的效果。
2. 非归档与归档方式,只用NOLOGGING是不起效果的。
3. 非归档下append已达到不错的效果,但不及与nologging的联用方式。
4. 归档下单append起不到效果。
NOLOGGING插完后最好做个备份。
另外,如果库处在FORCELOGGING模式下,此时的nologging方式是无效的。
总结得出以下3点结论:
a、非归档模式下,只需append就能大量减少redo的产生;归档模式下,只有append+nologging才能大量减少redo。
b、insert /*+ append */ 时会对表加锁(排它锁),会阻塞表上的除了select以外所有DML语句;传统的DML在TM enqueue上使用模式3(row exclusive),其允许其他DML在相同的模式上获得TM enqueue。但是直接路径加载在TM enqueue使用模式6(exclusive),这使其他DML在直接路径加载期间将被阻塞。
c、insert /*+ append */ 直接路径加载,速度比常规加载方式快。因为是从HWM的位置开始插入,也许会造成空间浪费。
数据库版本:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
网上说测试时不要使用auto trace来查看redo size,这个值是有偏差的.建议建立一个视图:
SQL> create or replace view redo_size
2 as
3 select value
4 from v$mystat, v$statname
5 where v$mystat.statistic# = v$statname.statistic#
6 and v$statname.name = 'redo size';
视图已创建。
一、非归档模式
SQL> archive log list
数据库日志模式 非存档模式
自动存档 禁用
存档终点 USE_DB_RECOVERY_FILE_DEST
最早的联机日志序列 95
当前日志序列 97
1、nologging表
SQL> create table test1 nologging as select * from dba_objects where 1=0;
表已创建。
SQL> select * from redo_size;
VALUE
----------
25714940
SQL> insert into test1 select * from dba_objects;
已创建72753行。
SQL> select * from redo_size;
VALUE
----------
34216916
SQL> insert /*+ APPEND */ into test1 select * from dba_objects;
已创建72753行。
SQL> select * from redo_size;
VALUE
----------
34231736
SQL> select (34231736-34216916) redo_append , (34216916-25714940) redo_normal from dual;
REDO_APPEND REDO_NORMAL
----------- -----------
14820 8501976
2、logging表:
SQL> create table test2 as select * from dba_objects where 1=0;
表已创建。
SQL> select * from redo_size;
VALUE
----------
34273348
SQL> insert into test2 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size;
VALUE
----------
42775336
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size;
VALUE
----------
42790156
SQL> select (42790156-42775336) redo_append , (42775336-34273348) redo_normal from dual;
REDO_APPEND REDO_NORMAL
----------- -----------
14820 8501988
二、归档模式下:
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE例程已经关闭。
SQL> startup mount
ORACLE例程已经启动。
Total System Global Area 477073408 bytes
Fixed Size 1337324 bytes
Variable Size 293603348 bytes
Database Buffers 176160768 bytes
Redo Buffers 5971968 bytes
数据库装载完毕。
SQL> alter database archivelog;
数据库已更改。
SQL> alter database open;
数据库已更改。
SQL> archive log list
数据库日志模式 存档模式
自动存档 启用
存档终点 USE_DB_RECOVERY_FILE_DEST
最早的联机日志序列 95
下一个存档日志序列 97
当前日志序列 97
1、nologging表
SQL> select * from redo_size;
VALUE
----------
17936
SQL> insert into test1 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size;
VALUE
----------
8490972
SQL> insert /*+ APPEND */ into test1 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size;
VALUE
----------
8506164
SQL> select (8506164-8490972) redo_append , (8490972-17936) redo_normal from dual;
REDO_APPEND REDO_NORMAL
----------- -----------
15192 8473036
2、logging表
SQL> select * from redo_size;
VALUE
----------
8506780
SQL> insert into test2 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size;
VALUE
----------
16979516
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size;
VALUE
----------
25518172
SQL> select (25518172-16979516) redo_append , (16979516-8506780) redo_normal from dual;
REDO_APPEND REDO_NORMAL
----------- -----------
8538656 8472736
在归档模式下,对于常规表的insert append产生和insert同样的redo
此时的insert append实际上并不会有性能提高.
但是此时的append是生效了的。
三、insert /*+ append */会阻塞除select以外的DML语句,direct-path insert操作是单独一个事务。
SQL> select count(*) from test2;
COUNT(*)
----------
291016
SQL> insert into test2 select * from dba_objects;
已创建72754行。
SQL> select count(*) from test2;
COUNT(*)
----------
363770
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;
已创建72754行
同一个session下:
SQL> select count(*) from test2;
select count(*) from test2
*
第 1 行出现错误:
ORA-12838: 无法在并行模式下修改之后读/修改对象
SQL> commit;
提交完成。
SQL> select count(*) from test2;
COUNT(*)
----------
436524
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;
已创建72754行。
SQL> shutdown immediate
ORA-01097: 无法在事务处理过程中关闭 - 请首先提交或回退
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
---------- ---------- ----------
224 0 1
SQL> select KADDR,TYPE,LMODE from v$lock where sid=224;
KADDR TY LMODE
---------------- -- ----------
0000000071BAE180 TM 6
0000000070CB11B8 TX 6
另外开启一个会话,就会发现只能select,其他DML全部阻塞。
快速向表中插入大量数据Oracle中append与Nologging的更多相关文章
- 在mysql数据库中创建oracle scott用户的四个表及插入初始化数据
在mysql数据库中创建oracle scott用户的四个表及插入初始化数据 /* 功能:创建 scott 数据库中的 dept 表 */ create table dept( deptno int ...
- ORACLE中如何找出大表分布在哪些数据文件中?
ORACLE中如何找出大表分布在哪些数据文件中? 在ORACLE数据中,我们能否找出一个大表的段对象分布在哪些数据文件中呢? 答案是可以,我们可以用下面脚本来找出对应表的区.段分别位于哪些数据文件 ...
- MySQL_(Java)使用JDBC向数据库中插入(insert)数据
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC向数据库中插入(insert)数据 传送门 MySQL_(Java)使用JDBC向数据库中删除(d ...
- ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- View中选择的数据行中的部分数据传入到Controller中
将View中选择的数据行中的部分数据传入到Controller中 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NE ...
- 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式
Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...
- C语言:将ss所指字符串中所有下标为奇数位上的字母转换成大写,若不是字母,则不转换。-删除指针p所指字符串中的所有空白字符(包括制表符,回车符,换行符)-在带头结点的单向链表中,查找数据域中值为ch的结点,找到后通过函数值返回该结点在链表中所处的顺序号,
//将ss所指字符串中所有下标为奇数位上的字母转换成大写,若不是字母,则不转换. #include <stdio.h> #include <string.h> void fun ...
- 003杰信-在jsp页面输入数据,然后在oracle数据库中插入factory数据,当字段允许为空时要特殊处理
本博客的内容全部来自于传智播客,特在此说明. 业务要求如下:在jsp页面(jFactoryCreate.jsp)上输入数据时,转到后台,并输入到数据库. jFactoryCreate.jsp页面:
- 【Oracle/Java】向三张表各插入百万数据,共用时18分3秒,平均每张表6分钟
三张表DDL如下: CREATE TABLE tb01 ( "ID" ,) not null primary key, "NAME" NVARCHAR2() n ...
随机推荐
- Python定时任务框架APScheduler 3.0.3 Cron示例
APScheduler是基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.基 ...
- html5移动端Meta设置
1. 强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览. <meta name="viewport" content= ...
- 移动端rem单位用法[转]
标签: 1.rem(font size of the root element)是指相对于根元素的字体大小的单位,em(font size of the element)是指相对于父元素的字体大小的单 ...
- 在PYTHON中使用StringIO的性能提升实测(更新list-join对比)
刚开始学习PYTHON,感觉到这个语言真的是很好用,可以快速完成功能实现. 最近试着用它完成工作中的一个任务:在Linux服务器中完成对.xml.gz文件的解析,生成.csv文件,以供SqlServe ...
- 单机搭建Android开发环境(四)
单机搭建安卓开发环境,前三篇主要是磨刀霍霍,这一篇将重点介绍JDK.REPO.GIT及编译工具的安装,下载项目代码并编译.特别说明,以下操作基于64位12.04 Server版Ubuntu.若采用其他 ...
- Java中的移位运算符
java中有三种移位运算符 << : 左移运算符,num << 1,相当于num乘以2 >> : 右移运算符,num >& ...
- MYSQL基础知识总结
!注释方式 # -- 单行 /* */ 多行 1.SELECT column1,column2,column3 FROM tablename WHERE id <= 5 ...
- qau-国庆七天乐——A
A - Who's in the Middle //先吐槽一波vj,不知道怎么回事,bits/stdc++.h不能用了...坑爹 7225007 upstar A Compile Error ...
- C#的一维数组和二维数组定义方式:
一维数组: //一维数组定义与初始化 ,, };//第一种方式 , , }; //第二种方式 int[] one3; //第三种方式 one3=,,}; 二维数组: //二维数组定义与初始化 //不规 ...
- Oracle 使用MERGE INTO 语句更新数据
/*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询,连接条件匹配 ...