数据库订正脚本性能优化两则:去除不必要的查询和批量插入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 无可挽回地失败了。      这里需要优化 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. 同时, 每次提交的插入事务变短, 可以减少锁等待时间。
 
时间: 2024-12-15 07:13:49

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

数据库设计与性能优化

转自:http://blog.51cto.com/jimshu/1250066 一.数据库设计与性能优化--概述 jimshu关注2人评论5892人阅读2013-07-16 08:02:14 前言 我1998年第一次接触SQL Server 6.5 for Windows NT 4.0,当时的感觉就认为SQL Server只是一个功能强大的Excel文件.现在回想起来,当年抱着这样一种态度,我开发的那些应用程序应该是非常幼稚的,其性能可想而知.记得那时候随便查询一笔记录就要花费十几秒,已是司空见

数据库的这些性能优化,你做了吗?

数据库的这些性能优化,你做了吗? 在互联网项目中,当业务规模越来越大,数据也越来越多,随之而来的就是数据库压力会越来越大.我们可能会采取各种方式去优化,比如之前文章提到的缓存方案,SQL优化等等,除了这些方式以外,这里再分享几个针对数据库优化的常规手段:「数据读写分离」与「数据库Sharding」. 作者:奎哥来源:数据库开发|2018-09-08 09:46 收藏 分享 在互联网项目中,当业务规模越来越大,数据也越来越多,随之而来的就是数据库压力会越来越大. 我们可能会采取各种方式去优化,比如

Python批量插入SQL Server数据库

因为要做性能测试,需要大量造数据到数据库中,于是用python写了点代码去实现,批量插入,一共四张表 简单粗暴地插入10万条数据 import pymssql import random __author__ = 'sryan' class GenerateData: def __init__(self): print('init') self.conn = None self.cur = None def connect(self, host, user, password, database

数据库mysql——MySQL 性能优化的最佳20多条经验分享

1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的. // 查询缓存不开启 $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()"); // 开启查询缓存 $today = date("Y-m-d"); $r = mysql_query("SELECT username

Android中数据库Sqlite的性能优化

1.索引简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包括对单表查询.连表查询.分组查询.排序查询.经常是一到两个数量级的性能提升,且随着数据数量级增长. (2). 缺点索引的创建和维护存在消耗,索引会占用物理空间,且随着数据量的增加而增加.在对数据库进行增删改时需要维护索引,所以会对增删改的性能存在影响. (3). 分类a. 直接创建索引和间接创建索引直

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

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

性能优化你必须知道的那些事儿

最近有客户反馈系统导入EXECL进行数据处理超时了,我当时的第一反应,不可能啊我明明是做过性能优化的啊,怎么还会超时呢,这是要有多少条数据才可能发生啊!于是找客户要来了EXECL,发现有7500多条数据,备份完客户数据库进行代码调试找出性能差的地方.都是一些平时老生常谈的东西,可是又是很容易忽略的地方,这里面就只谈两个点,使用String还是StringBuilder,校验数据正确性是在循环里面一条一条的使用SQL取数呢,还是一次性取出来在代码里面进行校验!下面将用实际数据结合图表,给出准确的答

MySQL设计规范与性能优化

引言 MySQL是目前使用最为广泛的关系型数据库之一,如果使用得当,可支撑企业级高并发.高可靠服务,使用不当甚至连并发量略高的个人网站都难以支撑: 就算使用了缓存,大量的数据库访问依旧在所难免,即使设置了较长的缓存有效期,而且缓存命中率较理想,但缓存的创建和过期后的重建都是需要访问数据库的: 本文主要从MySQL表结构设计规范和MySQL自身性能优化两方面来讨论该如何对MySQL数据库进行优化: MySQL表结构设计规范 1. 数据库设计命名规范 (1)数据库,数据表一律使用前缀,前缀名称一般不

SQL之性能优化

 在实际应用中,数据库中的数据会有很多,若要从这些数据表中检索数据,就需要对系统进行优化,提高数据库系统的响应速度,下面就是日常一些查询优化的方法. 1.创建索引 索引可以提高数据库查询的速度,提高数据库的访问性能,但同时也会影响数据更新操作(例如插入.修改.删除)的速度. 如果WHERE子句中经常用到的某一列或者某几列创建索引 为数据表中经常需要执行排序操作的列创建索引 多表连接时,应该为数据表的连接列创建索引 对于需要不断更新的列,则不建议创建索引 2.优化查询语句 避免在SELECT语