【发布时间】:2021-08-19 00:25:48
【问题描述】:
我正在使用 cx_Oracle 模块创建 sqlalchemy 引擎并使用 Python 和 Pandas 从 Oracle 数据库中检索数据,但我遇到了性能问题,并且出现了数据库错误。
如果我只指定几列,我的代码可以正常工作(但速度很慢),并且在很长一段时间后我可以获得所有 350 万行。这是我正在使用的代码:
import cx_Oracle
import pandas as pd
import config
from sqlalchemy import create_engine
engine = create_engine('oracle+cx_oracle://config.user:config.password@config.host:1521/?service_name=config.service')
sql = "select ITEM_NO, COUNTRY_CODE, LANGUAGE_CODE from table_ben_l_t where (LANGUAGE_CODE = 'es' and COUNTRY_CODE = 'ES')"
df = pd.read_sql(sql, engine)
添加更多列后,我将无法再运行此程序,因为在长时间延迟(我说的是几个小时)后出现数据库错误。
我知道使用这种方法来检索数据并创建 Pandas 并不是唯一可用的方法,但它绝对是最方便的……有没有更好/更安全的方法从 Oracle DB 中获取这些数据?我正在考虑逐块下载行,将它们转储到可以传递给 Pandas 的 dict 列表中,但这似乎不是很“优雅”......我相信一定有更好的方法来做这... :-)
提前感谢任何可以帮助我的人! :-)
JF
编辑 1: 回应@OldProgrammer 和@crocarneiro:
根据查询select * from all_ind_columns where table_name = 'TABLE_BEN_L_T';的结果,列没有索引
编辑 2: 这是我收到的错误消息:
DatabaseError: (cx_Oracle.DatabaseError) ORA-01555: snapshot too old: rollback segment number 509 with name "_SYSSMU509_3146905099$" too small
(Background on this error at: http://sqlalche.me/e/14/4xp6)
也非常感谢@Christopher Jones!这看起来很有趣!
【问题讨论】:
-
WHERE 子句中的列是否有索引?
-
当您说您遇到数据库错误时,您能详细说明一下吗?此外,如果您提及代码的用例,提供建议会更容易——您打算如何处理 350 万行?你真的需要这么多做进一步的处理等等
-
你好@OldProgrammer,我对一般数据库真的不是很熟悉,我只能编写类似于我使用的查询的简单查询。您能告诉我如何找到有关索引的信息吗?
-
嗨@jfpelletier,闯入:如果您使用的是oracle数据库并且想知道您的表中是否有任何索引,您可以执行以下查询:
select * from all_ind_columns where table_name = 'TABLE_BEN_L_T';。查询将返回索引的列和索引名称。如果您使用的是 SQL Developer、Toad 或其他 IDE,通常在表名中按 SHIFT + F4 或 CTRL + 单击会显示此信息。 -
您需要调整获取数据的批次数。从根本上说,这是由带有
fetcharraysize和更新的prefetchrows属性的 Pandas 下的 cx_Oracle 处理的。调整文档在这里Tuning Fetch Performance。另见oralytics.com/2018/11/14/…
标签: python pandas oracle cx-oracle