Sqlalchemy mySQL优化查询

2024-09-28 22:33:27 发布

您现在位置:Python中文网/ 问答频道 /正文

概述:

我需要从一个给定的数据库中创建一个统计工具,其中包含数十万个条目。所以我不需要写数据库,只需要获取数据。在

问题:

我有一个user表,在我的例子中,我选择20k个用户(两个日期之间)。现在我只需要选择至少花过一次钱的用户(从这些用户中)。在

为此,我有3个不同的表,其中保存了用户是否花钱的数据。(因此,我们总共有4张表):

User, Transaction_1, Transaction_2, Transaction_3

我目前所做的:

在User类的模型中,我创建了一个属性,用于检查用户是否出现在其中一个事务表中:

^{pr2}$

然后,我为男性和女性用户创建了两个计数器,这样我就可以计算出这2万用户中有多少人至少花了一次钱:

males_payed_atleast_once = 0
females_payed_atleast_once = 0

for male_user in male_users.all():
    if male_user.spent_money_once is True:
        males_payed_atleast_once += 1

for female_user in female_users.all():
    if female_user.spent_money_once is True:
        females_payed_atleast_once += 1

但这需要很长时间来计算,大约40-60分钟。我从来没有处理过这么大的数据量,也许这是正常的?在

其他信息:

如果您想知道male_users和{}是什么样子:

# Note: is this even efficient, if all() completes the query than I need to store the .all() into variables, otherwise everytime I call .all() it takes time
global all_users
global male_users
global female_users

all_users = Users.query.filter(Users.date_added >= start_date, Users.date_added <= end_date)
male_users = Users.query.filter(Users.date_added >= start_date, Users.date_added <= end_date, Users.gender == "1")
female_users = Users.query.filter(Users.date_added >= start_date, Users.date_added <= end_date, Users.gender == "2")

我试图将某些查询保存在全局变量中以提高性能。在

我使用python3 | Flask | Sqlalchemy来完成这个任务。数据库是MySQL。在


Tags: 用户数据库addeddateallqueryusersmale
2条回答

假设您需要在计数前将3个表的信息汇总在一起,这样会更快:

SELECT userid, SUM(ct) AS total
  FROM (
    ( SELECT userid, COUNT(*) AS ct FROM trans1 GROUP BY userid )
    UNION ALL
    ( SELECT userid, COUNT(*) AS ct FROM trans2 GROUP BY userid )
    UNION ALL
    ( SELECT userid, COUNT(*) AS ct FROM trans3 GROUP BY userid )
       )
  GROUP BY userid
  HAVING total >= 2

建议您在mysql命令行工具中进行测试,然后找出如何将其转换为python3 | Flask | Sqlalchemy

关于“隐藏数据库”的包,有趣的是,如果您要做任何不重要的事情,您仍然需要了解数据库是如何工作的。在

我现在尝试了一种完全不同的方法,使用了join,现在速度更快,它在10秒内完成查询,这花了60分钟

# males
paying_males_1 = male_users.join(Transaction_1, Transaction_1.user_id == Users.id).all()
paying_males_2 = male_users.join(Transaction_2, Transaction_2.user_id == Users.id).all()
paying_males_3 = male_users.join(Transaction_3, Transaction_3.user_id == Users.id).all()

males_payed_all = paying_males_1 + paying_males_2 + paying_males_3
males_payed_atleast_once = len(set(males_payed_all))

我只是连接每个表并使用.all(),结果很简单lists。在此之后,我合并所有列表并将它们键入set。现在我只有唯一的用户。最后一步是通过在set上使用len()对它们进行计数。在

相关问题 更多 >