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 ...
随机推荐
- spark共享变量
boradcast例子代码: scala版本 spark共享变量之Accumulator 例子代码: scala版本
- 软件推荐 - Source Insight
一直以来从事的开发工作,涉及的范围很杂,乱七八糟的都有,其中有一项占据了比较长的时间,那就是固件程序的开发,不涉及操作系统,也就是一般意义上大家所说的裸跑程序.用过的芯片杂七杂八,比较主要的有Ate ...
- socket模块
1 1.1 server: #!/use/local/env python# -*- coding:utf-8 -*- import socket ip_port = ('127.0.0.1', 99 ...
- java.util.concurrent Class ThreadPoolExecutor
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
- Java 编程实践
创建一个54个元素的整数数组,并将其元素值依次赋值为:1~54,用于表示一副牌的54张.再创建一个12个元素的整数数组,用于表示某玩家手中的牌,然后从前一数组中随机抽取12个元素赋值给该数组.打印后一 ...
- unity, 读写xls
可以用npoi: http://npoi.codeplex.com/ 把npoi.dll放在unity里即可. 读取代码: using System.IO;using NPOI.SS.UserMode ...
- 【转】.NET 安装和部署(Installer) 如何卸载上一个版本
前言 当使用.NET“安装项目”打包的安装文件,再次安装的时候会弹出如下提示,这个时候会让我们很郁闷,怎样才能自动卸载上一个安装的版本呢?方法很简单,只需简单的两个操作步骤即可解决. 操作步骤 主要由 ...
- [转]php和html混编的三种方式
php和html混编的三种方式 以下内容转自:http://blog.i1728.com/post/110.html 原文标题是:<PHP的(<<>,新标题是我加的,文章里的红 ...
- 并行计算之OpenMP中的任务调度
本文参考<OpenMP中的任务调度>博文,主要讲的是OpenMP中的schedule子句用法. 一.应用需求 在OpenMP并行计算中,任务调度主要用于并行的for循环.当for循环中每次 ...
- 带Cookie的 WebClient
/// <summary> /// WebClient的扩展 /// </summary> public class webClient : WebClient { /// & ...