Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Sqlalchemy mySQL优化查询_Python_Mysql_Sql_Performance_Sqlalchemy - Fatal编程技术网

Python Sqlalchemy mySQL优化查询

Python Sqlalchemy mySQL优化查询,python,mysql,sql,performance,sqlalchemy,Python,Mysql,Sql,Performance,Sqlalchemy,概述: 我需要从一个给定的数据库中创建一个统计工具,其中包含数十万个条目。所以我不需要写数据库,只需要获取数据 问题: 我有一个用户表,在我的例子中,我在两个日期之间选择了20k个用户。现在我只需要选择至少花过一次钱的用户 为此,我有3个不同的表,在这些表中,无论用户是否花钱,都会保存数据。因此,我们在这里共使用了4个表: User, Transaction_1, Transaction_2, Transaction_3 到目前为止我所做的: 在User类的模型中,我创建了一个属性,用于检查用

概述:

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

问题:

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

为此,我有3个不同的表,在这些表中,无论用户是否花钱,都会保存数据。因此,我们在这里共使用了4个表:

User, Transaction_1, Transaction_2, Transaction_3
到目前为止我所做的:

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

@property
def spent_money_once(self):
    spent_money_atleast_once = False
    in_transactions = Transaction_1.query.filter(Transaction_1.user_id == self.id).first()
    if in_transactions:
        spent_money_atleast_once = True
        return spent_money_atleast_once
    in_transactionsVK = Transaction_2.query.filter(Transaction_2.user_id == self.id).first()
    if in_transactionsVK:
        spent_money_atleast_once = True
        return spent_money_atleast_once
    in_transactionsStripe = Transaction_3.query.filter(Transaction_3.user_id == self.id).first()
    if in_transactionsStripe:
        spent_money_atleast_once = True
        return spent_money_atleast_once
    return spent_money_atleast_once
然后我为男性和女性用户创建了两个计数器,这样我就可以计算出这些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分钟。我从来没有处理过如此巨大的数据量,也许这是正常的

其他信息:

如果您想知道男性用户和女性用户的样子:

# 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")
我试图将某些查询保存在全局变量中以提高性能


我正在使用Python 3 | Flask | Sqlalchemy来完成此任务。数据库是MySQL。

我现在尝试了一种完全不同的方法并使用了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))

我只是简单地加入每个表并使用。所有结果都是简单的列表。在那之后,我将合并所有列表并将它们打印出来。现在我只有唯一的用户。最后一步是在集合中使用len对它们进行计数。

假设在计数之前需要将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命令行工具中进行测试,然后找出如何将其转换为Python 3 | Flask | Sqlalchemy


关于隐藏数据库的包的有趣之处-;如果要做任何非琐碎的事情,您仍然需要了解数据库是如何工作的。

您可以使用count获得大量记录。示例:male_payed_count=Users.query.filterUsers.date_added>=start_date,Users.date_added这个很遗憾不起作用,我也尝试过,但它不算任何东西。对于男性和女性,它返回0。这可能与hybrid_属性有关,但在更改为hybrid后,我得到了奇怪的结果,它只是计算了所有记录,忽略了花费的钱==True。我暂时不谈这3个事务表的意义是什么?您需要计算每个表中的重复次数吗?还是仅在所有3个的组合中?