数据库订正脚本性能优化两则:去除不必要的查询和批量插入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 ...
随机推荐
- [转]Android 延迟执行
开启新线程 new Thread(new Runnable(){ public void run(){ Thread.sleep(XXXX); handler.sendMessage(); //告诉主 ...
- Oracle利用external table 查看trace文件
1. 用下面的语句找到trace文件的路径 select * from v$diag_info where name='Default Trace File'; 2. 创建一个directory用来加 ...
- 注册表操作命令和自定义cmd窗口
REM @echo offREM clsREM echo Microsoft Windows 7REM echo ------------------------REM echo Welcome to ...
- bootstrap学习之三—插件
一.模态框(modal)插件 1)为要触发模态框的组件添加data-toggle="modal",data-target="对应ID" 2)使用一个div实现m ...
- itunes connect
https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/iTunesConnec ...
- 【推荐】使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享
使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工管理源码分享 在开始讲解之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery的U ...
- html中表格table的内容居中显示
align——表示左右居中——left,center,right valign——控制上下居中——left,center,right <td> 标签内加入: vertical-align ...
- Java基础之一组有用的类——使用正则表达式搜索子字符串(TryRegex)
控制台程序. 正则表达式只是一个字符串,描述了在其他字符串中搜索匹配的模式.但这不是被动地进行字符序列匹配,正则表达式其实是一个微型程序,用于一种特殊的计算机——状态机.状态机并不是真正的机器,而是软 ...
- SpinLock 实现
/* Example: SpinLock Description: SpinLock is the lock implementation using AtomicInteger as a primi ...
- IntelliJ IDEA 常用设置讲解2
IntelliJ IDEA 有很多人性化的设置我们必须单独拿出来讲解,也因为这些人性化的设置让我们这些 IntelliJ IDEA 死忠粉更加死心塌地使用它和分享它. 常用设置 如上图 Gif 所示, ...