如何减少sqlalchemy用于连接数据库和选择数据的时间

我是数据科学的初学者,最近的工作是使用python在某些条件下从公司的数据库中选择数据。我试图通过使用sqlalchemy和engine来实现这一点,但是花很长时间才能获得我需要的所有行。我看不到如何减少执行时间。 例如,我使用以下代码通过数据库中的store_id获取某个时间段内商店的总订单:

import pandas as pd
from sqlalchemy import create_engine,MetaData,select,Table,func,and_,or_,cast,Float
import pymysql

#create engine and connect it to the database
engine = create_engine('mysql+pymysql://root:*******@127.0.0.1:3306/db')
order = Table('order',metadata,autoload=True,autoload_with=engine)


#use the store_id to get all the data in two months from the table
def order_df_func(store_id):     
    df = pd.DataFrame()
    stmt = select([order.columns.gmt_create,order.columns.delete_status,order.columns.payment_time])
    stmt = stmt.where(
        and_(order.columns.store_id == store_id,order.columns.gmt_create <= datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),order.columns.gmt_create >= get_day_zero(last_month_start.date()) #func defined to get 00:00 for a day
                )
        )
    results = connection.execute(stmt).fetchall()
    df = pd.DataFrame(results)
    df.columns = results[0].keys()
    return df

#get the data in a specific time period
def time_bounded_order_df(store_id,date_required_type,time_period):
    order_df = order_df_func(store_id)
    get_date(date_required_type)# func defined to get the start time and end time,e.g. this week or this month
    if time_period == 't':
        order_df = order_df[(order_df['gmt_create'].astype(str) >= start_time) & (order_df['gmt_create'].astype(str) <= end_time)]
    elif time_period == 'l':
        order_df = order_df[(order_df['gmt_create'].astype(str) >= last_period_start_time) & (order_df['gmt_create'].astype(str) <= last_period_end_time)]
    return order_df

#get the number or orders
def num_of_orders(df):
    return len(df.index)

大约需要8秒钟才能获得40万个结果,这太长了。反正我可以调整代码使其更短吗?

更新

我试图直接在mysql工作台中选择数据,大约需要0.02s来获得1000个结果。我相信问题来自以下代码

results = connection.execute(stmt).fetchall()

但是我还是不知道可以将数据存储到pd.dataframe中。有什么想法吗?

Update2

我刚刚了解到表中有一些称为“索引”的东西可以减少处理时间。我的数据库由公司提供,我无法编辑。我不确定这是数据库中表的问题还是我需要做一些事情来修复我的代码。有没有一种方法可以“使用”代码中的索引?还是应该给予?还是可以通过python创建索引?

Update3

我发现选择多个列时数据库停止使用索引,这大大增加了处理时间。我相信这是一个mysql问题,而不是python问题。由于我几乎不了解sql,因此我仍在寻找解决方法。

Update4

我将mysql服务器版本从8.0降级到5.7,并且表中的索引开始工作。但是python处理仍然需要很长时间。我将继续努力找出解决办法。

kevin1985108 回答:如何减少sqlalchemy用于连接数据库和选择数据的时间

我发现如果我使用

results = connection.execute(stmt).fetchall()
df = pd.DataFrame(results)
df.columns = results[0].keys()

然后,您要将所有数据从数据库保存到python,并且由于我没有为python创建索引,因此保存时间和搜索时间非常长。但是,就我而言,我不需要在python中重新保存数据,我只需要几个变量的总数即可。因此,我只选择使用

,而不是选择几列
stmt = select([func.count(yc_order.columns.id)])
#where something something
results = connection.execute(stmt).scalar()
return results

它的运行速度与mysql内部一样快,问题得到解决

P.S。我还需要一些变量来计算每小时的总订单。我决定在数据库中创建一个新表,并使用schedule模块每小时运行一次脚本并将数据插入新表中。

本文链接:https://www.f2er.com/3112497.html

大家都在问