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

不必要的查询

请看以下语句:

    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 无可挽回地失败了。 如果要复现问题的话,也很简单: 先开始 insert X 大量记录, 然后马上敲入 delete X 语句, 等待 50s 后就会报出上述错误。
这里需要优化 sql 语句。 优化的办法是: 将 十几万条记录切分成多次提交, 每次提交 1000 条插入语句。代码如下:
def divideIntoGroups(allTuples, numPerGroup=1000):
'''
divide tuples into group of tuples ;
each group has no more than numPerGroup tuples
default value of numPerGroup is 1000
'''
groups = []
totalNum = len(allTuples)
if totalNum <= numPerGroup:
groups.append(allTuples)
return groups
start = 0
eachEnd = start + numPerGroup
while start < totalNum:
groups.append(allTuples[start:eachEnd])
start += numPerGroup
eachEnd = start + numPerGroup
if eachEnd >= totalNum:
eachEnd = totalNum
return groups def insertManyMany(insertSql, allTuples, db):
'''
insert many many records , usually more than 10000
insert 1000 once and insert (len/1000+1) times
'''
groups = divideIntoGroups(allTuples)
count = 0
for groupTuples in groups:
affectRows = db.executemany(insertSql, groupTuples)
if affectRows:
count += affectRows
db.commit()
needInsertNum = len(allTuples)
isPassedMsg = ('OK' if needInsertNum==count else 'SOME ERROR')
printAndLog("Need insert %d records, and actual %d. %s" % (needInsertNum, count, isPassedMsg))

调用方法如下:

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. 同时, 每次提交的插入事务变短, 可以减少锁等待时间。
 

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

  1. Python批量插入SQL Server数据库

    因为要做性能测试,需要大量造数据到数据库中,于是用python写了点代码去实现,批量插入,一共四张表 简单粗暴地插入10万条数据 import pymssql import random __auth ...

  2. 聊聊编程开发的数据库批量插入(sql)

    这里的批量插入,主要是支持SQL的大型存储数据库,本文以Mysql,Oracle,SqlServer,postgresql4类来说明,这大概是国内应用比较多的了.其余的应该可以按照这些去找.提到编程的 ...

  3. Android中数据库Sqlite的性能优化

    1.索引简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包括 ...

  4. MySQL数据库在IO性能优化方面的设置选择(硬件)

    提起MySQL数据库在硬件方面的优化无非是CPU.内存和IO.下面我们着重梳理一下关于磁盘I/O方面的优化. 1.磁盘冗余阵列RAID RAID(Redundant Array of Inexpens ...

  5. 高并发数据库之MySql性能优化

    1.慢查询 SHOW VARIABLES LIKE '%quer%'

  6. 高并发数据库之MySql性能优化实战总结

    向MySQL发送一个请求时MySQL具体的操作过程 慢查询 1.慢查询 SHOW VARIABLES LIKE '%quer%' 索引优化技巧 1.对于创建的多列索引(复合)索引,只要查询条件使用了最 ...

  7. Lua脚本性能优化指南

    https://github.com/flily/lua-performance/blob/master/Guide.zh.md https://springrts.com/wiki/Lua_Perf ...

  8. mysql性能优化学习笔记(2)如何发现有问题的sql

    一.使用mysql慢查询日志对有效率问题的sql进行监控      1)开启慢查询       show variables like ‘slow_query_log’;//查看是否开启慢查询日志   ...

  9. SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句

    1,查看CPU占用量最高的会话及SQL语句   select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...

随机推荐

  1. 使用dd工具对磁盘RAID5和10进行I/O性能测试

    很多情况下大家在对于理论深信不疑,理论是有前提条件的,不是所有的情况下都是正确的.恰逢公司有服务器,故进行了磁盘性能测试,当然测试的结果也只是顺序I/O性能测试(dd机制决定的). 前提条件:(DEL ...

  2. kernel 模块与简单 hello 模块

    Kernel 模块与简单 hello 模块 kernel 模块的简介 Linux 内核进行扩展时,例如编写驱动程序.netfilter功能等,最方便的方式是通过编写模块,然后加载到内核中.由于 ker ...

  3. Android --通知栏Notification

    参考博客:Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它) //创建一个通知栏的Builder构造类 (Create a Notification Bui ...

  4. Spring Boot 1 创建Demo

    Spring Boot的主要优点: 为所有Spring开发者更快的入门 开箱即用,提供各种默认配置来简化项目配置 内嵌式容器简化Web项目 没有冗余代码生成和XML配置的要求 入门操作: 1.打开ht ...

  5. shell中如何判断某一命令是否存在

    参考: http://www.cnblogs.com/tuzkee/p/3755230.html https://segmentfault.com/q/1010000000156870 http:// ...

  6. 解决git clone时报错:The requested URL returned error: 401 Unauthorized while accessing

    版本问题,最直接的解决办法就是重新编辑安装git吧: 1. 下载:# wget -O git.zip https://github.com/git/git/archive/master.zip 2. ...

  7. iOS 隐藏系统的导航,使用自定义的导航

    #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...

  8. Python之配置文件模块 ConfigParser

    写项目肯定用的到配置文件,这次学习一下python中的配置文件模块 ConfigParser 安装就不说了,pip一下即可,直接来个实例 配置文件 project.conf [db] host = ' ...

  9. 对ASP.NET Cookie的一些新的认识

    做用户登录,我一直用form验证的方式.有时候,为了节省时间,用户希望用户名输入框能够记住用户名,省得下次重新输入.这个时候光用form验证是不行的,因为form验证的话,用户一退出系统就失效了,所以 ...

  10. C++ note

    主要是为了学习c++的类和对象   内容摘自 c++概述 http://see.xidian.edu.cn/cpp/biancheng/cpp/rumen_1/   1,变量  ,C++中,我们可以在 ...