【问题标题】:pypyodbc retrieves data very slowly vs PLSQLpypyodbc 与 PLSQL 相比,检索数据非常慢
【发布时间】:2018-02-07 14:17:07
【问题描述】:

我在 PLSQL 与 Python/pypyodbc 中测试了相同的 Oracle 查询。我正在提取大约 30k 行,这在 PLSQL 中需要 27 秒,而在 Python 中大约需要 8 分钟。我的 python/pypyodbc 代码在这里:

import pandas as pd
import pypyodbc

q0 = '''
    select *
    from weatherview x
    where x.WeatherNodeRCIKey IN (481, 562, 563, 561, 564, 565, 560, 658)
    and x.WeatherDate >= '01-jan-2016'
   '''
try:
con = pypyodbc.connect(driver='{Oracle in OraClient11g_home1}', 
    server='oracle', uid='acct', pwd='Pass', dbq='table')

with con:
    cur = con.cursor()
    cur.execute(q0)
    q0_rows = cur.fetchall()
    q0_hdnm = [i[0] for i in cur.description]

except Exception as e:
    print("Error: " + str(e))

df0 = pd.DataFrame(q0_rows, columns=q0_hdnm)
df0.head()

我很难相信 Python 会这么慢。我很好奇这是服务器端/客户端问题,还是内存问题。我不认为这与代码的数据框/熊猫部分有关,因为我在没有最后几行的情况下运行了代码,结果相同。

我 90% 确定问题与 fetchall() 速度慢有关。

如果有人能指出我会很高兴:

  • 如何解决速度问题(数据库连接时间等)
  • 使用不同的包来拉取查询会更快
  • 使用 pypyodbc 更改此代码以更高效地工作

    编辑:由于我在下面找到的答案,我稍微更改了标签,删除了 [server-side],并添加了 [cx_Oracle]

【问题讨论】:

  • 一些事情。 1.等价的PL/SQL代码是什么样的? 2. fetchall() 是否使用数组接口? 3. 您可以使用 sqltrace 来查看数据库级别的差异(如果有的话)。
  • 感谢 BobC,1) pl/sql 代码与上面的三引号完全相同(我的 sql 可能很糟糕,但正如我所说,它的运行速度比 python 快得多)2) 不幸的是,我不知道这个问题的答案 3) sqlTrace 是在 DB 级别运行还是在 python 级别运行?你对我可以从哪里开始使用 sqlTrace 有任何建议(对我来说是新的)

标签: python oracle execute cx-oracle pypyodbc


【解决方案1】:

我通过上面的“使用不同的包”选项找到了一个答案,使用 cx_Oracle。代码如下:

import pandas as pd
import cx_Oracle

q0 = '''
    select *
    from weatherview_historical x
    where x.WeatherNodeRCIKey IN (481, 562, 563, 561, 564, 565, 560, 658)
    and x.WeatherDate >= '01-jan-2016'
    and x.WeatherTypeLu in (6436,6439)
   '''
try:
    #establish connection with profit (oracle) db
    con = cx_Oracle.connect(user='uid', password='pass', dsn='dsn_name')
    df0 = pd.read_sql_query(q0, con) 

except Exception as e:
    #return error message
    print("Error: " + str(e))

关键是 cx_Oracle 包,它在 20 秒内获取结果,而 pypyodbc 为 8 分钟(如上 PLSQL 为 27 秒)。我还能够通过 .read_sql_query 将行直接输入到 pandas 的数据框中

对于为什么 pypyodbc 与其他选项相比如此缓慢,我仍然非常感兴趣。如果有人对让它运行得更快有任何想法,无论是:

  • 在 sql 级别更改编码,因此 python 不必处理
  • 更改每次调用 DB 返回的项目数(数组大小/块大小)
  • 切换到服务器端
  • 跳过 .execute 或 .fetchall 步骤(这些步骤仍然可以与 cx_Oracle 一起使用)

请告诉我

【讨论】:

【解决方案2】:

使用turbodbc库,这是快速上传的唯一方法:https://turbodbc.readthedocs.io/en/latest/pages/getting_started.html

【讨论】:

    猜你喜欢
    • 2012-10-20
    • 1970-01-01
    • 2021-02-13
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 2016-12-01
    • 2015-01-27
    • 2014-09-06
    相关资源
    最近更新 更多