【问题标题】:Python- performance issue with mysql and google play subscriptionPython-mysql 和 google play 订阅的性能问题
【发布时间】:2016-06-15 13:36:01
【问题描述】:

我正在尝试按照以下步骤从 google play 中提取 purchase_state

    import base64
    import requests
    import smtplib
    from collections import OrderedDict
    import mysql.connector
    from mysql.connector import errorcode
    ......
  1. 查询数据库,从我的表中返回数千行带有purchase_idfield 的行
  2. 检查数据库中的每一行,并提取purchase_id,然后在google play 中查询所有这些。例如,如果我之前的结果 step是1000,1000次是查询google(刷新token+查询)。
  3. 将来自 google play 的新字段 purchase status 添加到新字典中,除了从 mysql 查询中获取的其他一些字段。
  4. 最后一步是对我的 dic 进行循环,然后准备所需的报告

编辑后:

def build_dic_from_db(data,access_token):
dic = {}
for row in data:

    product_id = row['product_id']
    purchase_id = row['purchase_id']
    status = check_purchase_status(access_token, product_id,purchase_id)
    cnt = 1

    if row['user'] not in dic:
        dic[row['user']] = {'id':row['user_id'],'country': row['country_name'],'reg_ts': row['user_registration_timestamp'],'last_active_ts': row['user_last_active_action_timestamp'],
                            'total_credits': row['user_credits'],'total_call_sec_this_month': row['outgoing_call_seconds_this_month'],'user_status':row['user_status'],'mobile':row['user_mobile_phone_number_num'],'plus':row['user_assigned_msisdn_num'],
                            row['product_id']:{'tAttemp': cnt,'tCancel': status}}
    else:
        if row['product_id'] not in dic[row['user']]:
            dic[row['user']][row['product_id']] = {'tAttemp': cnt,'tCancel':status}
        else:
            dic[row['user']][row['product_id']]['tCancel'] += status
            dic[row['user']][row['product_id']]['tAttemp'] += cnt
return dic

问题是我的代码运行缓慢〜总执行时间:448.7483880519867,我想知道是否有改进我的脚本。有什么建议吗?

【问题讨论】:

  • 瓶颈似乎来自google play请求。您是否考虑过创建多个执行程序以在单独的线程中查询数据库?
  • @Jean-FrançoisFabre 嘿,你能再解释一下吗,这是什么意思,我是 python 新手!为了通知你,我只有一个对 mysql 的 sql 查询而没有过滤,然后我将遍历所有 purchase_id,并且每次购买都查询谷歌。我没有在 mysql 中应用任何过滤,因为我的查询足够大,我试图在我的字典中构建过滤。

标签: python performance google-play-developer-api


【解决方案1】:

我希望我是对的,但瓶颈似乎是与 Playstore 的连接。按顺序执行将需要很长时间,而服务器一次能够处理一百万个请求。因此,这是一种使用执行程序处理作业的方法(您需要安装“并发”包) 在该示例中,您将能够同时发送 100 个请求。

from concurrent import futures
EXECUTORS = futures.ThreadPoolExecutor(max_workers=100)
jobs = dict()
for row in data:

   product_id = row['product_id']
   purchase_id = row['purchase_id']
   job = EXECUTORS.submit(check_purchase_status,
access_token, product_id,purchase_id)
   jobs[job] = row

for job in futures.as_completed(jobs.keys()):
   # here collect your results and do something useful with them :)
   status = job.result()
   # make the connection with current row
   row = jobs[job]
   # now you have your status and the row

顺便说一句,尝试使用临时变量,或者您经常使用相同的键访问您的字典,这不利于代码的性能和可读性。

【讨论】:

  • 看起来很棒!我要试试我的案子。我想确定一件事,在每一行中我只有一个购买 ID,所以每次我只向谷歌发送一个购买 ID,你认为这个解决方案是否适用于我的情况?我认为您的情况会非常适合使用 purchase_id 列表,而不仅仅是一个!你有什么意见?
  • 重点是:发送 1000 个请求而不会被 google 响应时间阻止,就像 1000 个用户同时做的那样。
  • 我已经编辑了我的问题,我无法理解如何发送 1000 个请求,我应该改变我编写函数的方式吗?
猜你喜欢
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 2023-02-09
  • 2019-03-17
  • 2013-01-21
  • 2018-06-09
  • 1970-01-01
  • 2017-10-07
相关资源
最近更新 更多