pandas 在python中使用cx_oracle库从数据库中获取600k记录的数据需要花费大量时间

juud5qan  于 2023-06-20  发布在  Python
关注(0)|答案(1)|浏览(191)

在python中使用cx_*oracle库和pandas www.example.com _*sql从数据库中获取数据时pd.read,需要花费一个小时才能将近600 000条记录获取到dataframe中。
我有至少6个查询运行同一案件。我试着把数据分块但没用
我试着分块的数据,并尝试优化查询,以及它仍然需要相同的时间。因为在 Dataframe 中的获取和加载花费时间。

hgb9j2n6

hgb9j2n61#

最新版本的cx_Oracle(已重命名为python-oracledb)默认情况下以“Thin”模式运行,这绕过了Oracle客户端库。这意味着在许多情况下,数据加载速度更快。请尝试python-oracledb。在精简模式下使用python-oracledb应该有助于提高性能。
安装步骤很简单,用python -m pip install oracledb之类的东西安装。请参阅升级文档。在python-oracledb上遵循的最佳实践。
上述响应中建议的调优也适用于python-oracledb。
在这里,我比较了获取600k行所花费的时间:
1.通过pandas的read_sql()和

  1. python-oracledb's fetchall().
    注意:我不确定你要获取的数据行的大小和类型,所以我使用了一个简单的数据集,有两列和600k行。我使用了Tuningpython-oracledb并修改了cursor. arraysize参数,这显著提高了获取行的性能。
    考虑:python-oracledb的fetchall()将数据作为元组列表返回,我已经考虑了从列表到本地pandas DataFrame的转换时间。
    | cursor.arraysize| pandas的read_sql()|python-oracledb fetchall()|
    | - -----|- -----|- -----|
    | 一百|3764秒|1846秒|
    | 一千|3690秒|一百八十五秒|
    | 一万|3695秒|二十三秒|
    | 十万|3712秒|22秒|
    根据行大小调整cursor.arraysize可以提高性能
    这是我使用python-oracledbfetchall()获取行并将其转换为pandas Dataframe的脚本。
import os
import time
import pandas as pd
import sqlalchemy as sql
import oracledb as oracledb

# Database Credentials
username = os.environ.get("PYTHON_USERNAME")
password = os.environ.get("PYTHON_PASSWORD")

cp = oracledb.ConnectParams()
cp.parse_connect_string(os.environ.get("PYTHON_CONNECTSTRING"))

eng = sql.create_engine(f'oracle+oracledb://{username}:{password}@{cp.host}:{cp.port}/?service_name={cp.service_name}')
tablename = input("enter table name: ")
cursorsize = input("enter cursor size: ")
sqlStatement = 'select * from {}'.format(tablename)
conn = eng.pool._creator()
start = time.time()
with conn.cursor() as cursor:
    cursor.arraysize = int(cursorsize)
    cursor.execute(sqlStatement)
    res = cursor.fetchall()
    #loading the result list in pandas Dataframe
    df = pd.DataFrame(res, columns = ['description','done'])
    elapsed = (time.time() - start)
    print("Prefetchrows:", cursor.prefetchrows, "Arraysize:", cursor.arraysize)
    print("Retrieved", len(res), "rows in", elapsed, "seconds")

请遵循以下最佳做法从Oracle数据库中提取大型数据行。
Python包使用的版本:

  • python-oracledb-1.3.1
  • pandas-1.5.3
  • SQLAlchemy-2.0.5

相关问题