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 ...
随机推荐
- scala言语基础学习九
模式匹配 case _ =>不能放在函数的中间必须放在最后,否则scala会编译不通过 在case 里面使用if守卫 在模式匹配中获取输入的数据(在匹配不到的情况下) 对类型进行匹配 case ...
- 配置duilib
前两天项目要用duilib重构.苦于网上几乎没有duilib的文档和教程,郁闷之极.那份简单文档上的代码都基本看懂了,就是不知道怎么配置,代码跑不起来! 网络上也几乎没有告诉第一次配置duilib的文 ...
- C++仿函数和typename的用法
1.仿函数的定义是很简单的,就是一个重载了括号()运算符的类,也被称为函数对象. 主要是用于个性化扩展算法对象.stl中实现了好多算法,每个算法都可以完成日常的大部分工作,设计者还允许你在这些强大的算 ...
- 爬虫入门---Python2和Python3的不同
Python强大的功能使得在写爬虫的时候显得十分的简单,但是Python2和Python3在这方面有了很多区别. 本人刚入门爬虫,所以先写一点小的不同. 以爬取韩寒的一篇博客为例子: 在Python2 ...
- Java中的简单工厂模式
举两个例子以快速明白Java中的简单 工厂模式: 女娲抟土造人话说:“天地开辟,未有人民,女娲抟土为人.”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面.女娲造人,这就 ...
- 使用SQL Server存储ASP.NET Session变量
创建和配置ASP.NET Session状态数据库 在基于NLB(网络负载平衡)环境下的ASP.NET Web应用程序开发,我们需要将Session存储在数据库中供多个Web应用程序调用,以下为配置方 ...
- Oracle字符集与客户端
http://www.linuxidc.com/Linux/2011-11/47383p2.htm 什么是Oracle字符集Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关 ...
- Python教程:[69]strip()函数详解
strip()用于裁剪字符串首尾的某些字符,是一个用处非常多的函数,今天我们来通过例子来探讨一下它的基本用法: 假如有一个这样的字符串 strip()不带任何参数,可以删除首位的空格 但是strip( ...
- apache使用ssl数字证书
apache配置: <VirtualHost *:443> ServerName web.p2 .com ProxyPreserveHost On ProxyRequests Off SS ...
- 【性能诊断】九、并发场景的性能分析(windbg案例,Fist Chance Exception/Crash dump)
经常会碰到这样的场景,自测及单单点的测试时没有任何问题,但在并发环境或生产环境下有时出现没规律的异常.报错等情况.在代码中增加日志是其中一种解决方式:抓取指定异常时的dump,通过wind ...