今天在mysql中插入大批量数据时,突然想起pymysql 还有executemany 方法,那么这两个方法到底谁快?快多少?
测试环境
python3
mysql
pymysql
老规矩,先上测试代码:
class IN_sql():
def __init__(self):
print('初始化中...')
self.connDB = pymysql.connect(host=DB_HOST,
user=DB_USER,
passwd=DB_PASSWD,
db=DB_DB,
charset='utf8mb4')
self.connDB.ping()
self.cu=self.connDB.cursor()
def workOn(self):
L=[]
with open("./1W.txt","r",encoding="utf-8")as f:
while True:
res=f.readline().replace("\r","").replace("\n","")
if not res:
break
L.append(res)
#统计插入所需时间
start = time.time()
sql = "insert ignore into article(an) values(%s);"
#execute 执行代码
for l in L:
self.cu.execute(sql, l)
#executemany 执行代码
#self.cu.executemany(sql, tuple(L))
self.connDB.commit()
print('共计用时(秒):' + str(round(time.time() - start, 2)))
self.cu.close()
self.connDB.close()
if __name__ == '__main__':
insert=IN_sql()
insert.workOn()
测试结果
方法量级耗时(s)
1W
10W
100W
execute
3.126
25.139
248.022
executemany
0.1
0.981
10.854
总结
可以看出明显的区别,,如果需要批量插入数据库,还是用 executemany方法好些,这个和execute 完全不是一个数量级!!!
==最近有朋友问到,executemany 和原生SQL 语句有好多的区别?==
这里本人又进行了测试:
def workOn(self):
L=[]
with open("./100W.txt","r",encoding="utf-8")as f:
while True:
res=f.readline().replace("\r","").replace("\n","")
if not res:
break
L.append(res)
#统计插入所需时间
start = time.time()
print("start time:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start)))
sql = "insert into article(an) values "
for l in L:
sql += "('%s'), " % l
sql = sql.rstrip(', ') + ';'
self.cu.execute(sql)
self.connDB.commit()
end=time.time()
print("end time:"+time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(end)))
print('共计用时(秒):' + str(round(end - start, 3)))
最终结果:20.176s
WHAT?
==为什么执行原生SQL 比executemany 还要慢啊?理论上原生SQL应该是最快的。==
通过查询源码得知,executemany实际上也是把各个参数组合成一条SQL语句执行(==insert into article(an) values (),(),(),(),(),()==),优化的地方主要是在字符串的拼接上。
最后经过测试得到:本人自己的代码字符串拼接花了12s左右的时间,写入SQL语句花了8s左右,而executemany 字符串拼接仅花了2s左右。
所以,小伙伴们以后遇到大批量数据写入时尽量使用executemany 方法吧!