您的位置:首页 > 博客中心 > 数据库 >

数据库订正脚本性能优化两则:去除不必要的查询和批量插入SQL

时间:2022-03-14 04:24

 

      最近在做多数据库合并的脚本, 要将多个分数据库的表数据合并到一个主数据库中。 以下是我在编写数据订正脚本时犯过的错误, 记录以为鉴。

 

       不必要的查询

       请看以下语句:     

    regiondb = db.Houyiregiondb()
    houyidb = db.Houyidb(read_only=False)

    regiondbRet = regiondb.query(vmmacsFromRegiondbSql)
    houyidbRet = houyidb.query(vmmacsFromHouyidbSql)

    if len(regiondbRet) == 0:
        return

        原意很明显, 是为了分别取出 houyidb 和 houyiregiondb 相应的记录, 用于后续对比。 但是这里不假思索地将 houyidb 查询的语句提前了, 结果可能导致  houyidb.query(vmmacsFromHouyidbSql) 成为不必要的查询。如果这个查询会拉取很多数据的话, 就会造成很大浪费。 字节就是钱啊! 如今的程序员或许不用像以前的程序员那么“抠门”, 也要“精打细算” 才是。 修复办法很简单, 调换下语句顺序即可:

regiondb = db.Houyiregiondb()
    regiondbRet = regiondb.query(vmmacsFromRegiondbSql)
    if len(regiondbRet) == 0:
        regiondb.close()
        return

    houyidb = db.Houyidb(read_only=False)
    houyidbRet = houyidb.query(vmmacsFromHouyidbSql)

        教训:  写程序切忌不假思索。

 

         锁超时

      并发操作主数据库时, 报 Lock wait timeout exceeded; try restarting transaction  锁超时错误。
经查, 是因为insert X 表的时候同时并发 delete from X where ... 。 insert 在先, delete X 语句等待锁。 由于 insert X 要插入十几万条记录, 耗费超过1分钟, 而 innodb_lock_wait_timeout = 50s ( show variables like "%timeout%";) 因此 delete X 无可挽回地失败了。

      调用方法如下:

      insertSql = "insert into student (name, age) value (%s, %s) "

      allTuples = [("zhang", 20), ("qian", 25), ("wang", 23), ... , ("liu", 26)]

      insertManyMany(insertSql, allTuples, db)

    效果很明显。 原来插入 32000 条记录需要 18s, 现在只需要 2-3s ,  原来插入 129968 条记录需要 67s , 现在只需要 12-15s. 同时, 每次提交的插入事务变短, 可以减少锁等待时间。
 

热门排行

今日推荐

热门手游