【问题标题】:Is there a way to speed up this Python script?有没有办法加速这个 Python 脚本?
【发布时间】:2021-04-15 13:44:53
【问题描述】:

我对 Python 还很陌生。我可以编写具有该功能的脚本,但我想知道是否可以做些什么来加快这个脚本的速度。

有任何错误或不必要/重复的动作吗?

这是上次运行的统计数据:

跟踪检查:[开始:2021-04-15-07:40:01 CST] [结束:2021-04-15-07:47:33 CST] [插入:172] [删除:1634] [玩家:120] [运行时间:0:07:32.203772]

我有 100,000 多名玩家要经历,因此我们非常感谢您的帮助!

提前致谢!

# https://requests.readthedocs.io/en/master/
import requests
# https://docs.python.org/3/library/datetime.html
import datetime
import mysql.connector
import json
import time
from time import sleep

currentTime2 = datetime.datetime.now()
currentTimeTime2 = currentTime2.strftime('%Y-%m-%d-%H:%M:%S')
cstTime = (currentTime2 - datetime.timedelta(hours=6))
cstTime2 = cstTime.strftime('%Y-%m-%d-%H:%M:%S')

# PRINT START TIME
def startTime():
    print('Tracking Check: [Start: ' + str(cstTime2) + ' CST] ', end="", flush=True)

# Script Timer
start_time = time.time()

# MySQL Connection - Open
# clanTrackingDb = mysql.connector.connect(host="db_IP", user="db_user", passwd="db-pass", db="DB")

# API Token
token = 'token'

cursor = clanTrackingDb.cursor()
cursor2 = clanTrackingDb.cursor()

activeClans = 0
inactiveClans = 0
clansGained = 0
clansLost = 0
playersInserted = 0
recordsDeleted = 0
recordsInserted = 0
valuesDelete = []
valuesInsert = []
valuesUpdate = []

# Clan Check Query
getPlayerTagsQuery = (
    "SELECT * FROM `playerRiverRaceHistory_merge` WHERE dataMerged = 'No' LIMIT 120")

cursor.execute(getPlayerTagsQuery)

result = cursor.fetchall()

resultCount = cursor.rowcount

tags = [i[1] for i in result]

for tag in tags:
    cursor5 = clanTrackingDb.cursor()

    getPlayerMergeStatusQuery = ("SELECT * FROM playerRiverRaceHistory WHERE playerTag = '%s'" % (tag))
                
    cursor5.execute(getPlayerMergeStatusQuery)

    getPlayerMergeStatusResult = cursor5.fetchall()

    getPlayerMergeStatusRowCount = cursor5.rowcount

    # print(str(tag) + ' - ' + str(getRiverRaceHistoryRowCount))

    if (getPlayerMergeStatusRowCount == 0):

        dataMerged = 'Yes'

        cursor3 = clanTrackingDb.cursor()
        updatePlayerMergeStatusQuery = ("UPDATE playerRiverRaceHistory_merge SET dataMerged = %s WHERE playerTag = %s")
        cursor3.execute(updatePlayerMergeStatusQuery, (dataMerged, tag))
        clanTrackingDb.commit()
        cursor3.close()

        #playersInserted = playersInserted + 1

    else:
        for x in getPlayerMergeStatusResult:
            db_playerTag = x[1]
            db_playerClanTag = x[3]
            db_playerClanName = x[4]
            db_warLeague = x[5]
            db_warDate = x[6]
            db_fameCollected = x[7]
            db_repairCollected = x[8]
            db_decksUsed = 0
            # print(str(db_playerTag) + ' - ' + str(db_warDate))

            cursor2 = clanTrackingDb.cursor()
            checkHistory2Query = ("SELECT * FROM playerRiverRaceHistory2 WHERE playerTag = '%s' AND playerClanTag = '%s' AND warDate = '%s'" % (db_playerTag, db_playerClanTag, db_warDate))         
            cursor2.execute(checkHistory2Query)
            checkHistory2Result = cursor2.fetchall()
            checkHistory2ResultRowCount = cursor2.rowcount

            if(checkHistory2ResultRowCount == 0):
                #print("Already in DB")
                # deleteHistoryQuery = ("DELETE FROM playerRiverRaceHistory WHERE playerTag = '%s' AND playerClanTag = '%s' AND warDate = '%s'" % (db_playerTag, db_playerClanTag, db_warDate))
                # cursor4 = clanTrackingDb.cursor()
                # cursor4.execute(deleteHistoryQuery)
                # clanTrackingDb.commit()
                # cursor4.close
                # #print("Record Deleted - 1")
                recordsDeleted = recordsDeleted + 1
                valuesDelete.append((db_playerTag, db_playerClanTag, db_warDate))
            else:
                #print("Not in DB")
                # insertHistory2Query = ("INSERT INTO playerRiverRaceHistory2 (playerTag, playerClanTag, playerClanName, warLeague, warDate, fameCollected, repairCollected, decksUsed) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)")
                # cursor4 = clanTrackingDb.cursor()
                # cursor4.execute(insertHistory2Query, (db_playerTag, db_playerClanTag, db_playerClanName, db_warLeague, db_warDate, db_fameCollected, db_repairCollected, db_decksUsed))
                # clanTrackingDb.commit()
                # cursor4.close
                #print("Data Inserted")
                recordsInserted = recordsInserted + 1
                valuesInsert.append((db_playerTag, db_playerClanTag, db_playerClanName, db_warLeague, db_warDate, db_fameCollected, db_repairCollected, db_decksUsed))

                dataMerged = "Yes"
                # cursor3 = clanTrackingDb.cursor()
                # updatePlayerMergeStatusQuery = ("UPDATE playerRiverRaceHistory_merge SET dataMerged = %s WHERE playerTag = %s")
                # cursor3.execute(updatePlayerMergeStatusQuery, (dataMerged, db_playerTag))
                # clanTrackingDb.commit()
                # cursor3.close()
                #print("Merge Status Updated")
                valuesUpdate.append((dataMerged, db_playerTag))

                # deleteHistoryQuery = ("DELETE FROM playerRiverRaceHistory WHERE playerTag = '%s' AND playerClanTag = '%s' AND warDate = '%s'" % (db_playerTag, db_playerClanTag, db_warDate))
                # cursor4 = clanTrackingDb.cursor()
                # cursor4.execute(deleteHistoryQuery)
                # clanTrackingDb.commit()
                # cursor4.close
                #print("Record Deleted - 2")
                recordsDeleted = recordsDeleted + 1
                valuesDelete.append((db_playerTag, db_playerClanTag, db_warDate))

            cursor2.close()

    cursor5.close()

insertHistory2Query = ("INSERT INTO playerRiverRaceHistory2 (playerTag, playerClanTag, playerClanName, warLeague, warDate, fameCollected, repairCollected, decksUsed) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)")
cursor6 = clanTrackingDb.cursor()
cursor6.executemany(insertHistory2Query, valuesInsert)
clanTrackingDb.commit()
cursor6.close()

updatePlayerMergeStatusQuery = ("UPDATE playerRiverRaceHistory_merge SET dataMerged = %s WHERE playerTag = %s")
cursor7 = clanTrackingDb.cursor()
cursor7.executemany(updatePlayerMergeStatusQuery, valuesUpdate)
clanTrackingDb.commit()
cursor7.close()

deleteHistoryQuery = ("DELETE FROM playerRiverRaceHistory WHERE playerTag = '%s' AND playerClanTag = '%s' AND warDate = '%s'")
cursor8 = clanTrackingDb.cursor()
cursor8.executemany(deleteHistoryQuery, valuesDelete)
clanTrackingDb.commit()
cursor8.close()

# Log Print
currentTime = datetime.datetime.now()
currentTimeTime = currentTime.strftime('%Y-%m-%d-%H:%M:%S')
currentTime2 = (currentTime - datetime.timedelta(hours=5))
currentTime3 = currentTime2.strftime('%Y-%m-%d-%H:%M:%S')

scriptTime = time.time() - start_time
scriptTime2 = str(datetime.timedelta(seconds=scriptTime))

startTime()
print('[Finish: ' + str(currentTime3) + ' CST] [Inserted: ' + str(recordsInserted) + '] [Deleted: ' + str(recordsDeleted) + '] [players: ' + str(resultCount) + '] [Runtime: ' + str(scriptTime2) + ']')

cursor.close()
cursor2.close()
clanTrackingDb.close()

【问题讨论】:

  • 这可能更适合Code Review,但在发布之前请阅读他们的指南
  • 如果它的工作和性能令您满意,并且您包含了足够多的 cmets,以便您在五年后阅读它时知道它在做什么,那么最好不要管它。如果您正在寻找一个广泛的批评,那么按照@Sayse 的建议去做。
  • 是的,这对 SO 来说太宽泛了。我唯一的观察是,您的问题似乎是数据量很大,但您的代码是 python 量很大。您没有使用 sql 的全部功能。就像你循环遍历一个选择的结果并执行另一个选择,然后基于之前的查询进行更新,所有这些都在 python 中处理。这可能在使用连接的 sql 中的单个更新查询中完成。
  • 请提供SHOW CREATE TABLE,以便我们知道桌子是什么样的。

标签: python mysql performance


【解决方案1】:
  • 听起来每个playerTag 都有多行。但是为什么每一行都有dataMerged?也许需要一个单独的Players 表?

  • SET dataMerged 至少出现 3 次 -- 制作一个子程序。

  • 一些可能有帮助的索引:

      INDEX(playerTag, playerClanTag, warDate)
      INDEX(dataMerged)
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 2013-01-10
    • 2019-10-04
    • 1970-01-01
    相关资源
    最近更新 更多