A-A+

pymysql 中 execute 和 executemany 使用方式和性能说明

2019年03月08日 13:38 汪洋大海 暂无评论 阅读 400 views 次

一.性能对比
今天突然想测试一下, pymysql中exectue ,和 executemany 插入数据库的效率,
看看区别大不大.
pymysql 中 execute 和 executemany 性能对比

users表结构

CREATE TABLE `users` (                                                            
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import pymysql
 
# 数据库配置信息
SHOUFUYOU_USER_PROFILE_CONFIG = {
    'host': 'xxx.xxx.xxx.xxx',
    'port': xxxx,
    'user': 'xxxx',
    'password': 'xxxxxxx',
    'db': 'xxxxx',
    'charset': 'utf8',
}
 
 
 
 
def fn_timer(fn):
    """
    计算 fn 的运算时间
    :param fn:
    :return:
    """
 
    @wraps(fn)
    def function_timer(*args, **kwargs):
        start = now()
        result = fn(*args, **kwargs)
        logger.info(f'{fn.__name__} total running time {now() - start} seconds')
        return result
 
    return function_timer
 
 
 
 
@fn_timer
def test_execute(connection, sql):
    rows_count = 0
    with connection.cursor(pymysql.cursors.DictCursor) as cursor:
        for i in range(1000):
            rows_count += cursor.execute(sql, ('frank@python.org', 'test' + str(i)))
        connection.commit()
 
    return rows_count
 
 
@fn_timer
def test_execute_many(connection, sql):
    with connection.cursor(pymysql.cursors.DictCursor) as cursor:
        datas = [('webmaster@python.org', 'test' + str(i)) for i in range(1,1000)]
        rows_count = cursor.executemany(sql, datas)
        connection.commit()
 
    return rows_count
 
 
if __name__ == '__main__':
    insert_sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
    connection = pymysql.connect(**SHOUFUYOU_USER_PROFILE_CONFIG)
 
    test_execute(connection, insert_sql)
    test_execute_many(connection, insert_sql)
 
 
###Connected to pydev debugger (build 173.4127.16)
###test_execute total running time 33.28491401672363 seconds
###test_execute_many total running time 0.12204098701477051 seconds

测试结果如下:

数据测试方法 耗时s 测试数据量
execute方法 3.287 100
executemany方法 0.0930 100
execute方法 33.284 1000
executemany方法 0.122 1000
execute方法 67.5612 2000
executemany方法 0.19372 2000
二. 总结
可以看出明显的区别, 如果需要批量插入数据库,还是用 executemany方法 这个和execute 不是一个数量级.
如果只是插入比较少的数量量 用 exectue 比较好点.

在使用pymysql的executemany方法时,需要注意的几个问题
1、在写sql语句时,不管字段为什么类型,占位符统一使用%s,且不能加上引号。例如

sql="insert into tablename (id,name) values (%s,%s)"

添加的数据的格式必须为list[tuple(),tuple(),tuple()]或者tuple(tuple(),tuple(),tuple())例如

values=[(1,"zhangsan")],(2,"lisi")]
#或者
values=((1,"zhangsan")],(2,"lisi"))

最后,通过executemany插入

cursor.executemany(sql,values) 

资料来源:https://blog.csdn.net/u010339879/article/details/81623833
https://blog.csdn.net/jy1690229913/article/details/79407224

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×

给我留言