A-A+
pymysql 中 execute 和 executemany 使用方式和性能说明
一.性能对比
今天突然想测试一下, 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
我想问一下,为什么占位符一律用%s,这是sql语句的规定吗?
我看到pymssql官网的例子是%d对应int类型
但是的确我用%f对应float的时候一直报错