データベースの訂正スクリプトの性能の最適化の2つ:不要なクエリと一括挿入SQLを削除します。



      最近では、複数のデータベースを統合するスクリプトをメインデータベースに統合します。以下はデータ訂正スクリプトを作成する際に犯したミスです。
 
       不必要なクエリ
       次の文を見てください。     
    regiondb = db.Houyiregiondb()

    houyidb = db.Houyidb(read_only=False)



    regiondbRet = regiondb.query(vmmacsFromRegiondbSql)

    houyidbRet = houyidb.query(vmmacsFromHouyidbSql)



    if len(regiondbRet) == 0:

        return
        本来の意味は、housidbとhouyire giondbそれぞれのレコードを取り出して、それを対比するためである。しかし、ここで何も考えずにhousidbで調べた語句を早まってしまい、結果としてhousidbで調べられてしまうかもしれません。 housyidb.query(vmmacs Froom HouyidbSql)は不必要なクエリとなります。このクエリが多くのデータを引き出すと、無駄になります。バイトはお金です。今のプログラマーは、昔のプログラマーのようにけちにしなくてもいいかもしれません。修復方法は簡単です。語句の順序を置き換えればいいです。
          
    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.   ,            ,          。