数据库订正脚本性能优化两则:去除不必要的查询和批量插入SQL
最近在做多数据库合并的脚本, 要将多个分数据库的表数据合并到一个主数据库中。 以下是我在编写数据订正脚本时犯过的错误, 记录以为鉴。
不必要的查询
请看以下语句:
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的更多相关文章
- Python批量插入SQL Server数据库
因为要做性能测试,需要大量造数据到数据库中,于是用python写了点代码去实现,批量插入,一共四张表 简单粗暴地插入10万条数据 import pymssql import random __auth ...
- 聊聊编程开发的数据库批量插入(sql)
这里的批量插入,主要是支持SQL的大型存储数据库,本文以Mysql,Oracle,SqlServer,postgresql4类来说明,这大概是国内应用比较多的了.其余的应该可以按照这些去找.提到编程的 ...
- Android中数据库Sqlite的性能优化
1.索引简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包括 ...
- MySQL数据库在IO性能优化方面的设置选择(硬件)
提起MySQL数据库在硬件方面的优化无非是CPU.内存和IO.下面我们着重梳理一下关于磁盘I/O方面的优化. 1.磁盘冗余阵列RAID RAID(Redundant Array of Inexpens ...
- 高并发数据库之MySql性能优化
1.慢查询 SHOW VARIABLES LIKE '%quer%'
- 高并发数据库之MySql性能优化实战总结
向MySQL发送一个请求时MySQL具体的操作过程 慢查询 1.慢查询 SHOW VARIABLES LIKE '%quer%' 索引优化技巧 1.对于创建的多列索引(复合)索引,只要查询条件使用了最 ...
- Lua脚本性能优化指南
https://github.com/flily/lua-performance/blob/master/Guide.zh.md https://springrts.com/wiki/Lua_Perf ...
- mysql性能优化学习笔记(2)如何发现有问题的sql
一.使用mysql慢查询日志对有效率问题的sql进行监控 1)开启慢查询 show variables like ‘slow_query_log’;//查看是否开启慢查询日志 ...
- SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句
1,查看CPU占用量最高的会话及SQL语句 select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...
随机推荐
- 使用dd工具对磁盘RAID5和10进行I/O性能测试
很多情况下大家在对于理论深信不疑,理论是有前提条件的,不是所有的情况下都是正确的.恰逢公司有服务器,故进行了磁盘性能测试,当然测试的结果也只是顺序I/O性能测试(dd机制决定的). 前提条件:(DEL ...
- kernel 模块与简单 hello 模块
Kernel 模块与简单 hello 模块 kernel 模块的简介 Linux 内核进行扩展时,例如编写驱动程序.netfilter功能等,最方便的方式是通过编写模块,然后加载到内核中.由于 ker ...
- Android --通知栏Notification
参考博客:Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它) //创建一个通知栏的Builder构造类 (Create a Notification Bui ...
- Spring Boot 1 创建Demo
Spring Boot的主要优点: 为所有Spring开发者更快的入门 开箱即用,提供各种默认配置来简化项目配置 内嵌式容器简化Web项目 没有冗余代码生成和XML配置的要求 入门操作: 1.打开ht ...
- shell中如何判断某一命令是否存在
参考: http://www.cnblogs.com/tuzkee/p/3755230.html https://segmentfault.com/q/1010000000156870 http:// ...
- 解决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. ...
- iOS 隐藏系统的导航,使用自定义的导航
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...
- Python之配置文件模块 ConfigParser
写项目肯定用的到配置文件,这次学习一下python中的配置文件模块 ConfigParser 安装就不说了,pip一下即可,直接来个实例 配置文件 project.conf [db] host = ' ...
- 对ASP.NET Cookie的一些新的认识
做用户登录,我一直用form验证的方式.有时候,为了节省时间,用户希望用户名输入框能够记住用户名,省得下次重新输入.这个时候光用form验证是不行的,因为form验证的话,用户一退出系统就失效了,所以 ...
- C++ note
主要是为了学习c++的类和对象 内容摘自 c++概述 http://see.xidian.edu.cn/cpp/biancheng/cpp/rumen_1/ 1,变量 ,C++中,我们可以在 ...