DB插入性能大乱斗-postgresqlvsmysqlvsmongodbvsoracle

因为看到德哥的postgresql与MongoDB插入100万条记录的比较文章,想动手验证一下,但结论反正让我看不懂了!

首先我是在虚拟机上测试,4核8G+存储,centos7.2,mongo3.2.9,postgresql9.6开发版,都是最新版,新安装不作任何处理;

都通过python来测试,但mongodb的测试结果是371秒,跟德哥的测试接近;
可pg就奇怪了,跑了十几分钟,还只看记录达到56万,实在是慢得出奇;

我估计存储方面有限制或者开发版有BUG吧,换物理机来测;
硬件,普通PC机,win10系统:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle
PG,之前官网下载的9.5.2windows版,全新安装不作任何设置:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle
这下能跑完了,但239秒跟德哥的测试有些差距,脚本中有一个区别,就是不是unix_socket连接(搞不清unix_socket连接名称在哪找);

由于mongodb还没装,但有一个很早之前下载的MySQL绿色版,版本号都6.0.5了,非官方,但能用:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle
小测一把,竟然102秒就跑完了!(后来我又在虚拟机上安装了mariadb5.5.50,测试结果也是102秒!)
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

这是PG的测试脚本:
import psycopg2
import time
conn=psycopg2.connect(database="test1",user="postgres",password="",host="127.0.0.1",port="5432")
cur=conn.cursor()
conn.autocommit=True
start_t=time.time()
print("START:"+str(start_t))
for i in range(0,1000000):
  cur.execute("insert into tt values(%(id)s,'digoal.zhou',32,'digoal@126.com','276732431')",{"id":i})
stop_t=time.time()
print("STOP:"+str(stop_t))
print(stop_t-start_t)

这是MySQL的测试脚本:
import MySQLdb
import time
conn=MySQLdb.connect(host="localhost",user="root",passwd="",db="test")
cur=conn.cursor()
conn.autocommit=True
start_t=time.time()
print("START:"+str(start_t))
for i in range(0,1000000):
  cur.execute("insert into tt values(%s,%s,%s,%s,%s)",(i,"digoal.zhou",32,"digoal@126.com","276732431"))
stop_t=time.time()
print("STOP:"+str(stop_t))
print(stop_t-start_t)

统一建表脚本(这个脚本在oracle,mysql,pg都能跑):
create table tt(id int, username varchar(20), age int, email varchar(20), qq varchar(20))

mongodb测试结果(mongodb3.2.9windows版,pymongo):
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle
297秒,比虚拟机的成绩要好,看来我这机器性能还是不错的^_^

由于机器上安装有oracle12.1,所以就来加入战局,DB大乱斗:
没想到测试结果竟然是368秒!附测试结果(python+cx_Oracle):
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

这下怎么解释啊,坦率地说,内心里面 对O偏爱>PG>mysql,但是被mysql实力打脸了^_^

分析oracle的原因,看来主要还是自动提交比较耗时,但问题是其他DB也是自动提交啊

plsql中,单次提交的效果,244秒与PG差不多:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

改成批量提交后85秒:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

不过如果oracle”火力全开“的话,最好成绩是1.28秒,当然,这个仅供参考,更公平的还是普通的写法:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle


在虚拟机上,用python测试插入100万记录竟然用了3001秒!暂时想不通原因,用plpgsql测试一把,只要5秒钟,找回了一点信心:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

plpgsql代码:
create or replace function pgins2(num bigint) returns bigint AS $$
declare 
    ii integer;
    beg_tm timestamp;
    end_tm timestamp;
    time_consuming bigint ;  
  begin
II:=1;
beg_tm:=now();
FOR ii IN 1..num LOOP
insert into tt values(ii,'digoal.zhou',32,'digoal@126.com','276732431');
end loop;
end_tm:=now();
select round(EXTRACT(EPOCH from end_tm)-EXTRACT(EPOCH from beg_tm)) into time_consuming;  
    return time_consuming;  
  end;
$$ LANGUAGE plpgsql;

2017-02-21更新:

再次在虚拟机上测试了PG9.2.8与最新的9.6.2正式版,如果自动提交打开的话,都需要2500多秒,而在同一台机上,mariadb只要159秒;
但当把自动提交关掉,变成插入后一次提交之后,PG9.6也只用了129秒:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle
这才是比较正常的结果,为什么虚拟机上与物理机在自动提交模式上差异这么大,也许跟PG的事务特性有关;

为了公平起见,又对maria_db的脚本也去掉了自动提交,再跑了一次:
DB插入性能大乱斗 -  postgresql vs mysql vs mongodb vs oracle

感觉mariadb对于自动提交与非自动提交并没有太大的差别,也许本身就作了优化吧;

总而言之,我觉得PG与MYSQL的表现都很好了;

分享标题:DB插入性能大乱斗-postgresqlvsmysqlvsmongodbvsoracle
本文地址:http://pwwzsj.com/article/jeecch.html