PLSQL_性能优化系列08_Oracle Insert / Direct Insert性能优化
2014-09-25 Created By BaoXinjian
应用设计不合理导致的session之间的互锁(enqueue)是影响程序可扩展性最常见的原因。此外,一些共享资源的争用,也会导致性能下降。
本篇介绍两个由并发insert操作导致的等待事件(wait event),以及如何通过优化物理设计来进行改善。
普通Insert操作本身产生的是行锁,因此进程相互之间不会锁住(enqueue),但当很多进程insert同一张表时,会有资源上冲突。
以下是两个例子:
1. Buffer busy wait
批量进程insert test_table表,当进程多时(超过100个)速度明显下降。在awr报告中看到(等待事件占了93%,cpu占0.95%。也就是说全都在等了,没人在干活…)。
进一步查到等待的object是PK_TEST_TABLE,是test_table表的主键。
Test_table表上建了hash分区(16),而PK_TEST_TABLE却没有建分区,导致修改同一index block,这会导致TX-index contention和buffer busy waits。
重建pk_test_table为hash分区索引后buffer busy waits和enq:TX-index contention就不在top events里了。
2. 很多进程insert,报ora-00060 Dead lock错误
insert/update/delete操作时,虽然是行封锁,但进程会在修改的block上占一个slot,当修改同一block的进程数量超过initrans时,可能导致60错误。见下文
Its possible to get an ora-60 deadlock when more than one transaction does DML on a block if INITRANS was set too low.
If there are more simultaneous transactions than slots then the transaction layer needs to grow from INITRANS towards MAXTRANS.
but it can't if the rest of the block is packed with data. In this case the transaction that could not get a slot will either hang or get an ora-60 depending on the particular circumstances.
This is an issue with tables, indexes, and clusters.
以上两种性能问题可以table/index的物理设计优化来解决。有几种方法:
(1). 建表时将表、索引的initrans值设大;
(2). 将表、索引建成hash分区,降低单个block上的冲突;
(3). 将索引建成反向索引。由于很多主键使用sequence的值,因此insert都是按sequence值排序的,insert时会在索引的同一block上产生冲突。使用反向键索引可以消除这一问题。有兴趣的可以在google上查相关概念。
数据库运行出账程序时,出现enq: TM - contention等待事件,
主要原因是多个进程在insert bill_invoice_*时,使用了insert /*+ append*/这一方式,本来想通过append即direct insert方式提升速度,结果产生表级锁。
这样开帐进程相互等待,实际上是变成串行的操作了,反而影响了速度。
更严重的是,如果是生产系统,还会导致账 单表上所有修改操作都无法进行,影响其他重要业务,这个后果就很严重了。
Direct insert这一用法有其速度快的优点,但也有其缺点,必须注意适用场合。大家想一下,为什么oracle不默认用append呢?
这里总结一下,direct-load insert(及append,direct方式sqlldr等)
适合于:
(1). 大量记录的insert时使用会提升速度,因为绕过databuffer直接访问数据文件,且不用扫描原有block上哪些有剩余空间,而直接分配新空间;
(2). 单个进程,通常是数据维护时,或者临时倒数据等;
这两种情况下,使用direct-load insert不仅速度快,还减少了数据库data buffer的使用,对数据库上的其他应用产生的影响也较小;
不适合:
(1). 少量记录insert。因为每次insert /*+append */后会进行索引维护,少量记录insert使用append反而慢;
(2). 多用户,OLTP环境。因为append会产生表级锁。OLTP系统除了一些批处理操作,大多数应用都不应该使用append;
1. append只在insert … select …中起作用,像insert /*+ append */ into t values(…)这类的语句是不起作用的。在update、delete操作中,append也不起作用。
2. append会使数据库不记录直接路径导入的数据的重做日志,会对恢复带来麻烦。
3. append直接在表段的高水位线以上写数据,不会重用高水位线以下的空间,会对空间的使用造成一定的浪费,对查询的性能也会造成一定的影响。
4. 用append导入数据后,如果没有提交或者回滚,则在同一个会话中不能对该表的执行任何DML或者SELECT操作,(执行查询或者DML会报错),但可以对其他表执行查询或者DML操作。
5. 用append导入数据后,如果没有提交或者回滚,在其他会话中任何对该表的DML都会被阻塞(不会报错),但对该表的查询可以正常执行。
Thanks and Regards
参考:http://www.linuxidc.com/Linux/2011-08/40763.htm
参考:http://mingyue19850801.blog.163.com/blog/static/19520820201071712231671/
PLSQL_性能优化系列08_Oracle Insert / Direct Insert性能优化的更多相关文章
- 性能优化系列八:MYSQL的配置优化
一.关键配置 1. 配置文件的位置 MySQL配置文件 /etc/my.cnf 或者 /etc/my.cnf.d/server.cnf 几个关键的文件:.pid文件,记录了进程id.sock文件,是内 ...
- Web性能优化系列:10个JavaScript性能提升的技巧
由 伯乐在线 - Delostik 翻译,黄利民 校稿.未经许可,禁止转载!英文出处:jonraasch.com.欢迎加入翻译小组. Nicholas Zakas是一位 JS 大师,Yahoo! 首页 ...
- SSE图像算法优化系列二十八:深度优化局部拉普拉斯金字塔滤波器。
基于局部拉普拉斯金字塔的Edge-aware滤波器是在2011年由Adobe 公司的研究员Sylvain Paris(大神级人物,写了很多文章)提出的,我在4年前曾经参考有关代码实现过这个算法,但是速 ...
- [MySQL性能优化系列]LIMIT语句优化
1. 背景 假设有如下SQL语句: SELECT * FROM table1 LIMIT offset, rows 这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处 ...
- [MySQL性能优化系列]提高缓存命中率
1. 背景 通常情况下,能用一条sql语句完成的查询,我们尽量不用多次查询完成.因为,查询次数越多,通信开销越大.但是,分多次查询,有可能提高缓存命中率.到底使用一个复合查询还是多个独立查询,需要根据 ...
- [MySQL性能优化系列]巧用索引
1. 普通青年的索引使用方式 假设我们有一个用户表 tb_user,内容如下: name age sex jack 22 男 rose 21 女 tom 20 男 ... ... ... 执行SQL语 ...
- WPF性能调试系列 – 内存监测
WPF性能调试系列文章: WPF页面渲染优化:Application Timeline WPF页面业务加载优化:Ants Performance Profiler WPF内存优化:Ants M ...
- WPF性能调试系列 – Ants Performance Profiler
WPF性能调试系列文章: WPF页面渲染优化:Application Timeline WPF页面业务加载优化:Ants Performance Profiler WPF内存优化:Ants Memor ...
- WPF性能调试系列 – 应用程序时间线
WPF性能调试系列文章: WPF页面渲染优化:Application Timeline WPF页面业务加载优化:Ants Performance Profiler WPF内存优化:Ants Memor ...
随机推荐
- JavaWeb学习记录(二十四)——获取插入数据后,自动生成的id值
public Integer insertObjects(final Goods entity) { // 定义sql语句 final String sql1 = "inser ...
- 2016 Hunan Province Programming Contest
2016 Hunan Province Programming Contest A. 2016 题意 \(1 \le a \le n, 1 \le b \le m\) ,其中\(1 \le n,m \ ...
- Android——网格布局仿计算器
代码如下: <?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android= ...
- java多线程:并发包中ReentrantLock锁的公平锁原理
一:锁的原理结构 (1)锁对象内部维护了一个同步管理器的对象AbstractQueuedSynchronizer,AbstractOwnableSynchronizer (2)该对象其实是一个抽象类, ...
- myeclipse10安装egit和使用
一.下载egit插件并安装到eclipse 下载egit插件包,然后解压放到Eclipse的dropins文件夹内或者直接放到对应的文件夹下 二.安装成功(window->preferences ...
- WCF入门教程一[什么是WCF]
一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...
- MySQL中char(36)被认为是GUID导致的BUG及解决方案
MySQL中char(36)被认为是GUID导致的BUG及解决方案 有时候在使用Toad或在程序中,偶尔会遇到如下的错误: System.FormatException GUID 应包含带 4 个短划 ...
- 006. C#使用WMI操作远程计算机
1. 使用WMI CIM studio 查看\root\CIMV2 所有可使用的表/字段(类/属性) , 点击下载 WMI CIM studio 2. 安装完成后打开VMI CIM studio
- nodejs 任务调度使用
使用的模块 node-schedule的使用 例子: 1:确定时间 var schedule = require("node-schedule");console.log(&quo ...
- python file operation
file.open(name[,mode[,buffering]]) 模式的类型有: r 默认只读 w 以写方式打开,如果文件不存在则会先创建,如果文件存在则先把文件内容清空(truncate ...