在 Python for 循环中慢 MySQL 数据库查询时间

Slow MySQL database query time in a Python for loop

我有一项任务是 运行 8 个相等的查询(每个国家/地区 1 个查询),并这样做 return 来自 MySQL 数据库的数据。我不能 运行 1 查询所有国家的原因是每个国家需要有不同的列名。此外,结果需要使用动态日期范围(过去 7 天)每天更新。是的,我可以 运行 所有国家并使用 Pandas 进行列命名和所有操作,但我认为以下解决方案会更有效。因此,我的解决方案是创建一个 for 循环,该循环使用预定义列表,其中包含所有国家/地区各自的维度和日期范围变量,这些变量会根据当前日期发生变化。我遇到的问题是 MySQL 在循环中查询 运行 比我直接在我们的数据仓库中 运行 相同的查询花费更多的时间(~140-500 秒对比 30 秒)。该解决方案适用于 DWH 的较小表格。问题是我不知道到底是哪个部分导致了问题以及如何解决它。

这是我的代码示例,其中实现了一些较小的 "tests":

#Import libraries:
from google.cloud import storage
from google.oauth2 import service_account
import mysql.connector
import pandas as pd
import time
from datetime import timedelta, date

#Create a connection to new DWH:
coon = mysql.connector.connect(
  host="the host goes here",
  user="the user goes here",
  passwd="the password goes here"
)

#Create Google Cloud Service credential references:
credentials = service_account.Credentials.from_service_account_file(r'C:\Users\ivo.vancans\OneDrive\Documents\Python Workspace\my credential json goes here.json')
project_id='my project id goes here'

cursor = coon.cursor()

#Create lists of countries and dimensions
countries = ['EE','FI','LV','LT']
appp_id_dim = ['ga:dimension5','ga:dimension5','ga:dimension5','ga:dimension5']
status_dim = ['ga:dimension21','ga:dimension12','ga:dimension20','ga:dimension15']
score_dim = ['ga:dimension11','ga:dimension11','ga:dimension19','ga:dimension14']

#Define the current date and date that was 7 days before current date:
date_now = date.today() - timedelta(days=1)
date_7d_prev = date_now - timedelta(days=7)

#Create a loop
for c,s in zip(countries, score_dim):
    start_time = time.time()
    #Create the query using string formating:
    query = f"""select ca.ID, sv.subType, SUM(svl.score) as '{s}'
    from aio.CreditApplication ca
    join aio.ScoringResult sr 
    on sr.creditApplication_ID = ca.ID 
    join aio.ScorecardVariableLine svl 
    on svl.id = sr.scorecardVariableLine_ID
    join aio.ScorecardVariable sv 
    on sv.ID = svl.scorecardVariable_ID
    where sv.country='{c}'  
    #and sv.subType ="asc"
    and sv.subType != 'fsc'
    and sr.created >= '2020-01-01'
    and sr.created between '{date_7d_prev} 00:00:00' and '{date_now} 23:59:59'
    group by ca.id,sv.subType"""

    #Check of sql query
    print('query is done', time.time()-start_time)

    start_time = time.time()
    sql = pd.read_sql_query(query, coon)
    #check of assigning sql:
    print ('sql is assigned',time.time()-start_time)

    start_time = time.time()
    df = pd.DataFrame(sql
                      #, columns = ['created','ID','state']
                      )
    #Check the df assignment:
    print ('df has been assigned', time.time()-start_time)

    #Create a .csv file from the final dataframe:
    start_time = time.time()
    df.to_csv(fr"C:\Users\ivo.vancans\OneDrive\Documents\Python Workspace\Testing Ground\{c}_sql_loop_test.csv", index = False, header=True, encoding='utf-8', sep=';')
    #Check csv file creation:
    print ('csv has been created',time.time()-start_time)

    #Close the session
    start_time = time.time()
    cursor.close()

    #Check the session closing:
    print('The cursor is closed',time.time()-start_time)

此示例有 4 个国家/地区,因为我尝试将数量减半,但这也无济于事。那是我认为我对 DWH 端有某种查询限制,因为主要的减速总是从第五个国家开始。 运行 它们分别花费几乎相同的时间,但仍然花费太长时间。 所以,我的测试表明循环总是滞后于查询数据的步骤。每隔一步花费不到一秒,但查询时间会增加到 140-500 秒,有时甚至更多,如前所述。那么,您认为问题是什么?

找到解决方案!在与我公司的一位对 SQL 和我们特定的 DWH 引擎有更多经验的人交谈后,他同意提供帮助并重写了 SQL 部分。我没有加入子查询,而是不得不重写它,这样就没有子查询了。为什么?因为我们的特定引擎不会为子查询创建索引,所以我敢打赌单独连接的表会有索引。这显着缩短了整个脚本的时间,从约 40 分钟 运行 缩短到约不到 1 分钟。