【问题标题】:More efficient way to make dynamic sql queries than iteration进行动态 sql 查询比迭代更有效的方法
【发布时间】:2022-01-13 22:46:36
【问题描述】:

我必须对整个表进行多个sql查询,并将它们连接成一个大数据表。

我有一个字典,其中键是团队名称,值用作首字母缩略词,其中首字母缩略词是 mySQL 数据表的前缀

    engine = create_engine('mysql+mysqlconnector://%s:%s@%s/%s' % (mysql_user, mysql_password, mysql_host, mysql_dbname), echo=False, pool_recycle=1800)
    
    mysql_conn = engine.connect()
    
    team_dfs = []
    
    nba_dict = {'New York Knicks': 'nyk',
        'Boston Celtics': 'bos',
        'Golden State Warriors': 'gsw',
        'New York Knicks': 'nyk'}
    
        for name, abbr in nba_dict.items()
    
            query = f'''
            SELECT *
            from {abbr}_record
            '''
            df = pd.read_sql_query(query, mysql_conn)

            df['team_name'] = name
    
            team_dfs.append(df)
    
    team_dfs = pd.concat(team_dfs)

有没有更好的方法来重构这段代码并使其更高效?

【问题讨论】:

  • 如果要一起查询,请不要将每个团队的记录分开。避免select *。不要试图围绕数据抢先优化你的代码。获取包含结构化数据的数据库,性能和简单代码将由此产生。
  • 100% 同意。我不是数据库管理员,上述任务的目标是创建一个黄金层表,将所有这些数据组合在一个地方。
  • 既然这是修复损坏架构的一次性任务,那么效率重要吗?

标签: python mysql performance iteration query-optimization


【解决方案1】:

如果你的nba_dict是固定的,可以使用UNION手动组合SQL的结果表。

abbr = list(nba_dict.values())

query = f'''
SELECT *
from {abbr[0]}_record UNION
SELECT *
from {abbr[1]}_record UNION
SELECT *
from {abbr[2]}_record UNION
SELECT *
from {abbr[3]}_record UNION
'''
df = pd.read_sql_query(query, mysql_conn)
df['team_name'] = list(nba_dict.keys())

【讨论】:

  • 这是一种更有效的方法,性能明智吗?因为在这种情况下,您要进行一个大查询,而不是 7 个单独的查询。
  • 你对效率和性能的定义是什么???
  • 我的定义是速度
  • UNION 重复数据删除。 UNION ALL 没有。重复数据删除可能不是正确的方法。
【解决方案2】:

当您需要一次检索多个团队的数据时,您的数据库布局(每个团队都有一个单独的表)注定效率低下。将所有数据放在一个表中会更好很多,为表提供一列,提及与每一行关联的团队。

为什么效率低下?更多表:更多工作。而且,更多查询:更多工作。

我建议你推倒这个数据库表结构的设计者,困难。坦率地说,它的设计是错误的。

如果您必须接受这种结构,我建议您创建以下视图。它将伪造单表方法并为您提供“黄金层”。你可以侥幸逃脱,因为职业体育特许经营权不会经常来去匆匆。您只需在数据库中执行一次。

CREATE OR REPLACE VIEW teams_record AS
SELECT 'nyk' team, * FROM nyk_record
UNION ALL
SELECT 'bos' team, * FROM bos_record
UNION ALL
SELECT 'gsw' team, * FROM gsw_record
UNION ALL .... the other teams

然后您可以通过SELECT * FROM teams_record ORDER BY team 获取所有数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 2020-05-21
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    相关资源
    最近更新 更多