首页 > 解决方案 > python多处理与ibm_db2?

问题描述

我正在使用 python ibm_db2 模块从 db2 LUW 读取大约 1500 万条数据。我正在读取每百万的数据一次又一次地读取这些数据以避免内存问题。这里的问题是完成一个循环读取一百万个数据,它需要 4 分钟。我如何使用多处理来避免延迟。吹是我的代码。

start =0
count = 15000000
check_point =  1000000

chunk_size = 100000
connection = get_db_conn_cur(secrets_db2)
for i in range(start, count, check_point): 
       query_str = "SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY a.timestamp) row_num, * from table a) where  row_num between " + str( i + 1) + " and " + str(i + check_point) + "" 
        
       number_of_batches = check_point // chunk_size
       last_chunk = check_point - (number_of_batches * chunk_size) 
       counter = 0 
       cur = connection.cursor()
       cur.execute(query_str) s
        
       chunk_size_l = chunk_size 
       while True:
         counter = counter + 1 
         columns = [desc[0] for desc in cur.description] 
         print('counter', counter)
         if counter > number_of_batches: 
              chunk_size_l = last_chunk 
         results = cur.fetchmany(chunk_size_l) 
         if not results:
            break 
         df = pd.DataFrame(results)
         #further processing 

标签: pythonpython-3.xdb2multiprocessing

解决方案


这里的问题不是多处理。是您读取数据的方法。据我所知,您使用 ROW_NUMBER() 只是对行进行编号,然后每个循环获取 100 万行。

由于您没有对此使用任何 WHERE 条件,table a因此您运行的每个循环都会导致 FULL TABLE SCAN 。您在 Db2 服务器上浪费了太多 CPU 和 I/O 只是为了获得一个行号,这就是为什么每个循环需要 4 分钟或更长时间。

此外,这远不是获取数据的有效方法。只要数据在程序期间发生变化,您就可以进行重复读取或幻读。但这是另一个主题的主题。

您应该使用此处描述的 4 种获取方法之一从 SQL CURSOR 中逐行读取。这样,您将使用非常少量的 RAM,并且可以有效地读取数据:

sql = "SELECT * FROM a ORDER BY a.timestamp"
stmt = ibm_db.exec_immediate(conn, sql)
dictionary = ibm_db.fetch_both(stmt)

while dictionary != False:
    dictionary = ibm_db.fetch_both(stmt)

推荐阅读