美文网首页
insert into优化

insert into优化

作者: 是东东 | 来源:发表于2020-08-13 10:29 被阅读0次

结果:

  • 通过navicat客户端操作
    • 插入一万条数据,批量执行和单执行分别耗时0.217秒和5分钟。
    • 插入十万条数据,批量执行,耗时11秒。
  • 通过python操作
    • 插入十万条数据,批量执行,耗时1秒。

案例:

单个执行,执行完成花了5分钟左右
for i in range(10000):
    a = "INSERT INTO `apps`.`apiapp_card` (`id`, `card_id`, `card_user`, `add_time`) VALUES ('%s', '', 'test123', '2019-12-17');"%str(i+1)
    with open("a.txt", "a") as fp:
        fp.write(a+"\n")

把生成的文本复制出来 ,多个INSERT INTO 对应的 sql 一次性贴到 navicat 客户端执行,如下图


批量执行,执行完成花了0.217秒,速度明显提高不少
insert_sql = "INSERT INTO `apps`.`apiapp_card`  VALUES "
with open("b.txt", "a") as fp:
        fp.write(insert_sql+"\n")
for i in range(10000):
    a = "('%s', '', 'test123', '2019-12-17'),"%str(i+10001)
    with open("b.txt", "a") as fp:
        fp.write(a+"\n")

注意最后一条数据后面不是逗号,改成分号,否则语法报错

  • 部分数据内容展示如下
    INSERT INTO apps.apiapp_card VALUES
    ('10001', '', 'test123', '2019-12-17'),
    ('10002', '', 'test123', '2019-12-17'),
    ......
    ('20000', '', 'test123', '2019-12-17');

复制生成的 INSERT INTO 到 navicat 客户端执行


假设10W条数据直接插入mysql 这时候报错:Err 1153 - Got a packet bigger than ‘max_allowed_packet’ bytes,
报错原因:由于数据量较大,mysql 会对单表数据量较大的 SQL 做限制,10w条数据的字符串超出了max_allowed_packet的允许范围。

先在 navicat 输入命令查看 max_allowed_packet 最大允许包

show global variables like ‘max_allowed_packet’;

image.png

解决:

修改my.cnf配置文件
在[mysqld]部分添加一句,如果有就修改对应的值:
max_allowed_packet=40M
这里的值,可以用 M单位,修改后,需要重启下mysql就可以生效了

再次重新执行上面10w条数据,查看运行结果总共花11秒左右时间。

以上操作均用navicat客户端,若直接用python去执行,会花多少时间呢?

dbinfo = {
    "host": "192.168.1.x",
    "user": "root",
    "password": "123456",
    "port": 3306}
class DbConnect():
    def __init__(self, db_cof, database=""):
        self.db_cof = db_cof
        # 打开数据库连接
        self.db = pymysql.connect(database=database,
                                  cursorclass=pymysql.cursors.DictCursor,
                                  **db_cof)
        # 使用cursor()方法获取操作游标
        self.cursor = self.db.cursor()
    def select(self, sql):
        # SQL 查询语句
        # sql = "SELECT * FROM EMPLOYEE \
        #        WHERE INCOME > %s" % (1000)
        self.cursor.execute(sql)
        results = self.cursor.fetchall()
        return results
    def execute(self, sql):
        # SQL 删除、提交、修改语句
        # sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
        try:
          # 执行SQL语句
          self.cursor.execute(sql)
          # 提交修改
          self.db.commit()
        except:
          # 发生错误时回滚
          self.db.rollback()
    def close(self):
        # 关闭连接
        self.db.close()
if __name__ == '__main__':
    import time
    insert_sql = "INSERT INTO `apps`.`apiapp_card`  VALUES "
    insert_values = "".join(["('%s', '', 'test123', '2019-12-17'), \n"%str(i+100000) for i in range(100000)])
    # 拼接sql
    sql = insert_sql + insert_values[:-3]+";"
    # print(sql)
    # 执行sql
    time1 = time.time()
    db = DbConnect(dbinfo, database="apps")
    db.execute(sql)
    db.close()
    time2 = time.time()
    print("总过耗时:%s" % (time2-time1))

python执行结果:
总过耗时:1.0816256999969482
10w条数据只要1秒钟

相关文章

网友评论

      本文标题:insert into优化

      本文链接:https://www.haomeiwen.com/subject/zxqbdktx.html