access update语句执行_用pymysql实现对多行数据的insert和update加速

70a65b976df9b70bd64c0354939f803b.png

摘要

本文对pymysql操作MySQL,insert和update的速度优化测试对比。对于insert操作来说,“一个事务处理多行的方式”比“一个事务处理一行的方式”插入相同的数据快了313倍,即插入2000个记录,一个事务一行的方式需要30.99秒,优化方式仅需要0.099秒。MySQL原始语法是支持对insert语句一次插入多行记录,即insert into table_name values ,后面跟着多行值。

但是对于update语句来说,MySQL并没有原始的语法支持一次update处理多行记录,update原始语句仅支持一次处理多个字段。本文将update语法和case when 语法结合起来,可以实现一个事务update更新多行记录,经测试这种方式比常规的方式快了283倍,即处理2000个记录,常规方式需要31.19秒,优化方式仅需要0.11秒。

pymysql包操作MySQL数据库

我们可以用Python封装一个MySQL连接的类,在类中实现对MySQL操作的类方法。

例如,我们可以新建一个MySqlConnector的类,实现初始化类方法如下:

6cc09f8b40fff57438c90d6b154a2c51.png

这个方法中,首先从mysql_config.ini配置文件中,加载MySQL的配置数据,如host、port、user、pwd、db_name等;然后利用pymysql包的连接方法,创建一个MySQL的连接。

然后,我们定义MySqlConnector类的查询方法:

0ce4d2490c774d4b24e859c5124dd058.png

这个方法可以执行对mysql的查询操作。

其次,我们再定义MySqlConnector类的update方法:

f5f2f256e49b9acb7244c7a8a9745a25.png

这个update方法,可以执行对mysql的插入、更新、删除操作。

最后,定义MySqlConnector类的close方法:

41eb63472d4368124681db516e3c558d.png

对MySQL查询或者其他操作执行完毕之后,一定要执行该方法,关闭mysql的连接。因为单位时间里MySQL的连接数有最大的上限,当Mysql的连接数太多时,会造成MySQL的性能下,甚至会出现事务进程卡死的情况。

对insert 多行数据的性能优化

我们先定义一个函数来计算某个函数的执行时间:

727b5961f10253de0e153453c798136b.png

我们网上任意找2000个文字,来做这个优化对比测试:

514cffd8807abf9c2bed38f40636cec2.png

所以现在的任务是需要将这2000行的文本,插入mysql中。

1、我们先定义一种插入方式:一个事务插入一行数据的方式

c42c872b42cd3702c8eedff75b7ddec8.png

执行看看需要多少时间:

1f00f37875d3a008e372b4c036f07fe5.png

我们得到,一个事务插入一行的方式,将2000个文本全部插入,需要30.99秒。

2、我们定义另一种方式:一个事务插入多行记录值

eda71f9f01fdcd4cc4737c264bb5bdbd.png

看看这种方式的执行时间:

28b7bd6e4c9e00db97c7db0447678cb0.png

我们发现这种方式,插入2000行数据,仅需要0.099秒,比之前的方式,速度快了313倍。

对update多行数据的性能优化

同样地,使用如上的2000行文本数据,现在需要根据 id 将mysql中的某个字段更新成这个2000行文本。

1、常规的方式是

a525673e4f0fdd9a5619476943d1d035.png

执行耗时:

a5591d83bed0a51aace86dff712702e2.png

这种一个事务更新一行记录的方式,处理2000行数据,需要耗时31.19秒。

2、能不能写成一个事务更新多行的方式

虽然MySQL原生语法,没有一次update更新多行记录的语法。但是,我们可以结合case when 语法,很优雅的实现这个需求。

a9533b584d38daadd5c65a315a36f1e3.png

执行时间:

33dca9bacaf7fd4a01997c946a1ac477.png

发现,采用这种方式,更新2000行文本的时间,仅需要0.11秒,比常规方式加速了283倍。

小结

对于MySQL的insert和update的操作,尽可能的使用一个事务处理多行记录值的方式,这样可以大大提升对MySQL的操作性能。另外需要注意的时,当使用一个事务处理多行记录值时,可能会出现如下的报错信息:"Got a packet bigger than 'max_allowed_packet' bytes"。

一个事务处理多行虽好,但是事务处理多行也是有最大上限的。当出现这个报错信息时,需要将数据分成几个batch,然后每个batch来使用一个事务处理多行的方式即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在pymysql模块,可以使用cursor对象的lastrowid属性来获取最后插入的行的id。例如: ``` import pymysql conn = pymysql.connect(host='localhost', user='root', password='123456', database='testdb') cursor = conn.cursor() sql = "INSERT INTO users (name, age) VALUES ('John', 25)" cursor.execute(sql) # 获取插入的id last_id = cursor.lastrowid print(last_id) conn.commit() cursor.close() conn.close() ``` 在上面的例子,我们先执行了一条insert语句,然后通过cursor对象的lastrowid属性获取了插入的id。注意,获取插入id的前提是在执行insert语句之前开启了一个连接,并且在执行insert语句后进行了commit操作。 ### 回答2: 在pymysql模块执行insert语句后,可以使用`lastrowid`属性来获取插入数据的id。 首先,我们需要建立数据库连接,并创建一个游标对象。然后,使用游标对象执行insert语句,例如: ```python # 导入pymysql模块 import pymysql # 建立数据库连接 conn = pymysql.connect(host='localhost', port=3306, user='root', password='password', db='test') # 创建游标对象 cursor = conn.cursor() # 执行insert语句 sql = "INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2')" cursor.execute(sql) # 获取插入数据的id insert_id = cursor.lastrowid # 提交事务 conn.commit() # 关闭游标和数据库连接 cursor.close() conn.close() # 输出插入数据的id print("插入数据的id为:", insert_id) ``` 在执行`cursor.lastrowid`时,会返回最后插入数据的自增id。 需要注意的是,使用`cursor.lastrowid`方法只能在插入数据之后调用,如果在执行insert语句之前调用该方法,它将返回0。另外,使用`lastrowid`属性的前提是表有自增id字段,且该字段的值为自增。如果表没有自增id字段,则`lastrowid`方法将返回0。 以上是通过pymysql模块执行insert后返回插入数据的id的方法。 ### 回答3: 在pymysql模块执行insert语句后获取插入数据的id可以通过两种方式实现。 第一种方式是使用"SELECT LAST_INSERT_ID()"语句查询最后插入的数据的id。具体步骤如下: 1. 执行insert语句,插入数据数据库。 2. 使用cursor对象的execute()方法执行"SELECT LAST_INSERT_ID()"语句。 3. 使用cursor对象的fetchone()方法获取查询结果。 4. 最后插入数据的id就可以通过查询结果获得。 示例代码如下: ```python import pymysql # 连接数据库 conn = pymysql.connect(host='localhost', user='root', password='password', database='testdb') # 创建游标对象 cursor = conn.cursor() # 执行insert语句 cursor.execute("INSERT INTO table_name (column1, column2) VALUES (%s, %s)", ("value1", "value2")) # 查询最后插入数据的id cursor.execute("SELECT LAST_INSERT_ID()") result = cursor.fetchone() inserted_id = result[0] # 关闭游标和数据库连接 cursor.close() conn.close() # 输出插入数据的id print(inserted_id) ``` 第二种方式是使用pymysql的connection对象的insert_id属性获取最后插入的数据的id。具体步骤如下: 1. 执行insert语句,插入数据数据库。 2. 使用connection对象的insert_id属性获取最后插入的数据的id。 示例代码如下: ```python import pymysql # 连接数据库 conn = pymysql.connect(host='localhost', user='root', password='password', database='testdb') # 创建游标对象 cursor = conn.cursor() # 执行insert语句 cursor.execute("INSERT INTO table_name (column1, column2) VALUES (%s, %s)", ("value1", "value2")) # 获取最后插入数据的id inserted_id = conn.insert_id() # 关闭游标和数据库连接 cursor.close() conn.close() # 输出插入数据的id print(inserted_id) ``` 无论使用哪种方式,都需要在执行insert语句之后立即获取插入数据的id,才能获得正确的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值