试图找到将 SQL Query 转换为具有大量记录的 Pandas DataFrame 的最有效方法

Posted

技术标签:

【中文标题】试图找到将 SQL Query 转换为具有大量记录的 Pandas DataFrame 的最有效方法【英文标题】:Trying to find the most efficient way to convert SQL Query to Pandas DataFrame that has large number of records 【发布时间】:2018-10-15 11:45:25 【问题描述】:

我正在尝试查询 MS-SQL 数据库视图并将结果转换为 Pandas DataFrame。

以下是我尝试的两种不同方法,在这两种情况下,查询并转换为具有 415076 条记录的 DataFrame 都需要约 439.98 秒(约 7 分钟)(这次是将其转换为 DataFrame,而不是用于数据检索)。这是我的应用业务逻辑对用户请求的数据输入/检索部分的典型案例。

注意:对于记录较少的查询(例如在 x1000 中),查询结果到 DataFrame 的转换性能在这两种情况下都很快。

query = """ SELECT * 
            FROM db_view_name 
            WHERE CONDITION_1 = %d AND
            CONDITION_2 IN (%s) """ %(int(val), ','.join(map(str, my_values_list)))
con = pyodbc.connect(con_string)

Case 1:
    cursor = con.cursor()
    result = cursor.execute(query)
    items = [dict(zip([key[0] for key in cursor.description], row)) for row in result]
    df = pd.DataFrame(items)

Case 2:
    df = pd.read_sql_query(query, con)

我的环境:我正在使用 Python 3.6 和 Pyramid Web 框架和 SQLAlchemy ORM。

如何减少处理这么多记录所需的时间?对此问题的任何帮助将不胜感激:)

【问题讨论】:

为了澄清,您能否确认不是数据检索而是转换为数据帧需要这么长时间? 我在描述中更新了,谢谢@Thornhale 尝试 from_records 避免 items 构建:pd.DataFrame.from_records(result, columns=[key[0] for key in cursor.description]) @Parfait 我尝试使用 from_records 但仍然需要相同的时间来执行。 【参考方案1】:

仅供参考(我们已经讨论过)。

上面几行代码中比较慢的部分是 SQL 返回到 pandas 数据帧的转换。鉴于 Python 的默认行为,这一步不仅速度慢而且是单线程的。

为了避免这种行为,一种强制处理的方法是在单独的进程中发送 x 个子查询。

一旦我们得到子查询的结果,通过 pd.concat 组装单个数据帧实际上很快。

由于您正在研究并行化任务,请考虑以下“分布式计算”库:

黎明:http://dask.pydata.org/en/latest/ 分布:http://docs.enthought.com/distarray/ 雷:https://ray-project.github.io/2017/05/20/announcing-ray.html

如果您愿意将其他库添加到依赖项列表中,所有这些都使您能够以更高的自动化程度并行化任务。

另一种方法是在 Python 核心本身中使用多进程功能。

【讨论】:

非常感谢您的想法@Thornhale

以上是关于试图找到将 SQL Query 转换为具有大量记录的 Pandas DataFrame 的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

如何将一系列记录转换为 SQL 中该范围之后的记录值?

Big Query (SQL) 将多列转换为行/数组

如何以编程方式将 HQL 转换为 SQL 查询(不记录)

SQL Query只查找具有一种产品类型的用户

JOOQ 插入到具有大量记录的选择中

使用新的 wp_query 将 sql 查询转换为 wordpress 查询