0
cx_Oracle API对我来说非常快,直到我尝试使用CLOB值。性能:如何使用cx_Oracle和executemany()快速插入CLOB?
我做如下:
import time
import cx_Oracle
num_records = 100
con = cx_Oracle.connect('user/[email protected]')
cur = con.cursor()
cur.prepare("insert into table_clob (msg_id, message) values (:msg_id, :msg)")
cur.bindarraysize = num_records
msg_arr = cur.var(cx_Oracle.CLOB, arraysize=num_records)
text = '$'*2**20 # 1 MB of text
rows = []
start_time = time.perf_counter()
for id in range(num_records):
msg_arr.setvalue(id, text)
rows.append((id, msg_arr)) # ???
print('{} records prepared, {:.3f} s'
.format(num_records, time.perf_counter() - start_time))
start_time = time.perf_counter()
cur.executemany(None, rows)
con.commit()
print('{} records inserted, {:.3f} s'
.format(num_records, time.perf_counter() - start_time))
cur.close()
con.close()
主要担心的问题是我表现:
100 records prepared, 25.090 s - Very much for copying 100MB in memory! 100 records inserted, 23.503 s - Seems to be too much for 100MB over network.
有问题的步骤是
msg_arr.setvalue(id, text)
。如果我评论它,脚本只需要几毫秒即可完成(当然,将空值插入到CLOB列中)。其次,在
rows
数组中添加与CLOB变量相同的引用似乎很奇怪。我在互联网上找到了这个例子,它工作正常,但我做对了吗?有没有方法来提高我的情况下的性能?
更新:测试网络吞吐量:一个107 MB的文件通过SMB在11 s内复制到同一主机。但是,网络传输不是主要问题。数据准备需要非常多的时间。
首先要测量您的网络速度。您可能只需使用ftp传输100MB就可以开始。这会给你一个想法,但是oracle使用不同的协议。接下来是跟踪会话。 – steve
@steve,增加了网络速度信息:它可能比这里快两倍,但主要瓶颈是准备CLOB变量。 – greatvovan
行“rows.append((id,msg_arr))#???”是循环的一部分,这看起来不正确。如果这没有帮助,那么可以获得该函数的代码覆盖性能数据。我不认为这个问题与oracle相关,而是与cx_oracle库的实现有关。 – steve