我正在使用jaydebeapi(Mac OS X)查询Netezza数据库并执行一些快速/脏时间:
t0 = time.time()
curs.execute('''select * from table1;''')
print time.time() - t0
我自己创建了表,它包含650,000行和9列(整数和日期)。
当我运行上述命令时,它需要大约1.3分钟才能完成(平均超过10次)。
然后,当我尝试获取数据时:
t0 = time.time()
curs.execute('''select * from table1;''')
row = curs.fetchone()
while row is not None:
row = curs.fetchone()
print time.time() - t0
完成大约需要10分钟(平均超过10次)。
现在,当我使用WinSQL(Windows 7,ODBC)运行相同的SQL查询时,返回数据大约需要3分钟。我似乎无法弄清楚为什么它在Python中花了这么长时间,我不确定如何或从哪里开始寻找。
答案 0 :(得分:2)
您是将JayDeBeApi与JPype结合使用还是与Jython结合使用?使用JPype实现获取大型结果集会导致对每个单元格值进行一些JNI调用,从而导致大量开销。 您应该考虑以下选项之一:
答案 1 :(得分:1)
您可能希望使用curs.fetchmany()而不是fetchone。这将在某种程度上优化来回来获取行。
这样的事情甚至可以隐藏你一次获取多行的事实:
def fetchYield(cursor):
li = []
while True:
if not li:
li = cursor.fetchmany()
if not li:
raise StopIteration
yield li.pop(0)
for row in fetchYield(curs):
<do something with row>
但是,我认为如果原始sql查询工具需要3分钟来获取数据,那么让Python代码花费3倍的时间并不是完全没有道理的。
答案 2 :(得分:1)
我遇到了类似的问题,我发现使用fetchall
进行了改进,并将游标arraysize
参数设置为详细信息(详细信息为1),如DB-API documentation中报告JayDeBeApi
是基于。
cursor = conn.cursor()
cursor.arraysize = 10000
cursor.execute("select * from table1")
rows = cursor.fetchall()
# storing data in a pandas DataFrame
df = pd.DataFrame(data=rows, columns = ["C1", "C2", "C3"])
cursor.close()
我在600.000行中取得了以下表现
arraysize = 10000 --- 509 seconds
arraysize = 1 --- 526 seconds
然而,与使用相同JDBC驱动程序的基于Java的客户端相比,我也观察到更长的获取时间。正如9000所说,我的建议是花费一些时间在你的SQL查询上,让数据库完成工作,这是一个更快,更具可扩展性的解决方案。