设为首页 收藏本站
查看: 505|回复: 0

[经验分享] ORACLE数据库插入性能测试

[复制链接]

尚未签到

发表于 2016-7-24 10:02:44 | 显示全部楼层 |阅读模式
  
ORACLE数据库插入性能测试

MKing
2010-3-8

测试环境基本信息:
OS:Windows XP sp3
DB:Oracle 9.2.0.1 未启用归档
DB重做日志文件大小:100MB
硬盘型号:SAMSUNG HD161GJ(SATA-300,160G,7200rpm,8M cache)
CPU:Intel Core2 E8400(3.0G)
内存:2G

通过HD Tune得到的硬盘基本测试信息,
IOPS:66
读取:90MB/s
写入:82MB/s

测试表脚本:

create table T_EMPLOYEE
(
ID NUMBER(10) not null,
NAME VARCHAR2(20) not null,
CREATE_DATE DATE default sysdate not null,
BIRTHDAY DATE,
ADDRESS VARCHAR2(200),
EMAIL VARCHAR2(200),
MOBILEPHONE VARCHAR2(11),
TELEPHONE VARCHAR2(20),
IDENTITY_CARD VARCHAR2(18),
WEIGHT NUMBER,
HEIGHT NUMBER
)


插入10万条记录,采用Java JDBC方式的测试结果如下(单位:秒):

执行方式
OCI
TCP/IP

OCI
IPC

thin
AutoCommit=true

thin
AutoCommit=false

Statement(test1)
69.84
67.03
66.96
42.81
PreparedStatement(test2)
40
37.18
39.21
12.66
PreparedStatement Batch(test3)
51.72
50.78
2.81
2.81


从测试结果可以看出,采用thin连接方式 batch插入的性能最好,而采用oci的batch插入性能未得到提高,也可能是bug。
记得以前在ORACLE文档里说采用oci模式的性能最好,9i中经过测试完全不成立,我想可能是以前java本身性能的问题,现在java语言的性能已经非常好了,thin连接方式不管是从管理还性能方面来说都是首选了。

注:采用oci的batch插入性能未得到提高确实是BUG,后来把ORACLE客户端升级到9.2.0.8,花的时间只要6s,但还是比thin的方式差。

以下是测试程序源码:
import java.sql.*;
import java.util.Calendar;

public class inserttest {
public static void test1(Connection iConn) throws SQLException{
Statement statement = iConn.createStatement();
String str_i;
for (int i=1;i<10000;i++) {
str_i=new Integer(i).toString();
String vSQL = "insert into t_employee(id,name,birthday,address,email,mobilephone,telephone,identity_card,weight,height)/n"
+ "values(seq_t_employee_id.nextval,'张三"+str_i+ "',sysdate - "+str_i+","
+ "'上海市南京东路11号203室"+str_i+"',"
+ "'abcd"+str_i+"@gmail.com',"
+ "'138'|| trim(to_char("+str_i+", '00000000')),"
+ "'021-'|| trim(to_char("+str_i+", '00000000')),"
+ "'3504561980' || trim(to_char("+str_i+", '00000000')),"
+ "64,1.72)";
//System.out.println(vSQL);
statement.executeUpdate(vSQL);
}
}

public static void test2(Connection iConn) throws SQLException{
String vSQL = "insert into t_employee(id,name,birthday,address,email,mobilephone,telephone,identity_card,weight,height)/n"
+ "values(seq_t_employee_id.nextval,'张三'||?,sysdate - ?,"
+ "'上海市南京东路11号203室'||?,"
+ "'abcd'||?||'@gmail.com',"
+ "'138'|| trim(to_char(?, '00000000')),"
+ "'021-'|| trim(to_char(?, '00000000')),"
+ "'3504561980' || trim(to_char(?, '00000000')),"
+ "64,1.72)";
PreparedStatement ps = iConn.prepareStatement(vSQL);
String str_i;
for (int i=1;i<10000;i++) {
str_i=new Integer(i).toString();
ps.setString(1, str_i);
ps.setString(2, str_i);
ps.setString(3, str_i);
ps.setString(4, str_i);
ps.setInt(5, i);
ps.setInt(6, i);
ps.setInt(7, i);
ps.executeUpdate();
}
}

public static void test3(Connection iConn) throws SQLException{
String vSQL = "insert into t_employee(id,name,birthday,address,email,mobilephone,telephone,identity_card,weight,height)/n"
+ "values(seq_t_employee_id.nextval,'张三'||?,sysdate - ?,"
+ "'上海市南京东路11号203室'||?,"
+ "'abcd'||?||'@gmail.com',"
+ "'138'|| trim(to_char(?, '00000000')),"
+ "'021-'|| trim(to_char(?, '00000000')),"
+ "'3504561980' || trim(to_char(?, '00000000')),"
+ "64,1.72)";
PreparedStatement ps = iConn.prepareStatement(vSQL);
String str_i;
for (int i=1;i<10000;i++) {
str_i=new Integer(i).toString();
ps.setString(1, str_i);
ps.setString(2, str_i);
ps.setString(3, str_i);
ps.setString(4, str_i);
ps.setInt(5, i);
ps.setInt(6, i);
ps.setInt(7, i);
ps.addBatch();
//ps.executeUpdate();
}
ps.executeBatch();
}

public static void main(String[] args) throws ClassNotFoundException,SQLException {
Class.forName("oracle.jdbc.driver.OracleDriver");
//Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:mydb", "yzs", "yzs");
Connection conn = DriverManager.getConnection("jdbc:oracle:oci8:@mydb", "yzs", "yzs");
java.util.Date d1=Calendar.getInstance().getTime();
conn.setAutoCommit(false);
test2(conn);
java.util.Date d2= Calendar.getInstance().getTime();
System.out.println("es:"+(d2.getTime()-d1.getTime())+"ms");
conn.commit();
conn.close();
}
}

采用服务器PL/SQL 方式插入10万条记录的测试结果如下:
注:t_e1与t_employee同样的表结构

执行方式
说明
运行时间
(单位:秒)
pl/sql insert(脚本1)
普通insert
3.203
pl/sql forall insert(脚本2)
从一个表BULK COLLECT INTO到目标表
0.578
insert into select *(脚本3)
使用insert into select方式插入
0.156
insert /*+ append*/ into select *(脚本4)
加append hint的插入
0.234

从测试结果分析,采用insert into select 的方式最快,只要0.156s,根据数据量统计,平均每行大小为134字节,总共插入数据量为134*100000=12.78MB,可得每秒约插入81MB的数据,基本上达到了硬盘的上限。
而采用append hint插入反而更慢,从同事讨论结果得到,采用append的insert会采用direct-path插入,因此数据会直接写入数据文件,所以消耗的时间更多。

--------------------------------------------脚本1--------------
declare
i integer;
begin
for i in 1 .. 100000 loop
insert into t_employee
(id,
name,
birthday,
address,
email,
mobilephone,
telephone,
identity_card,
weight,
height)
values
(
seq_t_employee_id.nextval,
'张三' || i,
sysdate - i,
'上海市南京东路11号203室' || i,
'abcd' || i || '@gmail.com',
'138' || trim(to_char(i, '00000000')),
'021-' || trim(to_char(i, '00000000')),
'3504561980' || trim(to_char(i, '00000000')),
64,
1.72);
end loop;
commit;
end;
--------------------------------------------脚本1--------------

--------------------------------------------脚本2--------------
DECLARE
TYPE table_t_employee IS TABLE OF t_employee%ROWTYPE;
v_table table_t_employee;
BEGIN
SELECT * BULK COLLECT INTO v_table FROM t_employee;
FORALL idx IN 1 .. v_table.COUNT
INSERT INTO t_e1 VALUES v_table (idx);
COMMIT;
END;
--------------------------------------------脚本2--------------


--------------------------------------------脚本3--------------
insert into t_e1 select * from t_employee
--------------------------------------------脚本3--------------


--------------------------------------------脚本4--------------
insert /*+ append*/ into t_e1 select * from t_employee
--------------------------------------------脚本4-------------

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-248523-1-1.html 上篇帖子: Oracle 10g Data Pump Expdp/Impdp 详解 下篇帖子: Oracle 数据库字典,视图,基表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表