You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Notebook中500万行数据批量取数过慢,求优化方案

高效批量获取Oracle大数据量的优化方案

1. 调大游标数组大小(最直接的优化)

原代码每次fetchall()后循环append,而且cx_Oracle默认游标arraysize只有100,这会导致频繁的网络IO交互,拖慢速度。直接把arraysize设成更大的值(比如10000甚至100000,根据服务器内存情况调整),然后批量拉取数据,能大幅减少网络往返次数。

示例代码:

import cx_Oracle

# 建立数据库连接
conn = cx_Oracle.connect("用户名/密码@数据库地址")
cursor = conn.cursor()
# 调整数组大小,越大单次拉取的数据越多
cursor.arraysize = 10000

sql = """SELECT name_employer
         FROM my_table
         WHERE section = 'OTHER'"""

data = []
cursor.execute(sql)
# 循环批量拉取直到没有数据
while True:
    batch_rows = cursor.fetchmany()
    if not batch_rows:
        break
    data.extend(batch_rows)

cursor.close()
conn.close()

2. 换掉ROWNUM分页,避免重复扫表

原代码用ROWNUM嵌套分页的方式,每次查询都要重新扫描整个表中符合section='OTHER'的数据,500万行的话重复扫表的开销极大。可以改用基于主键/唯一有序列的分页,比如表有主键id的话,每次只拉取上次批次之后的数据,彻底避免重复扫表:

示例代码(假设表有主键id):

import cx_Oracle

conn = cx_Oracle.connect("用户名/密码@数据库地址")
cursor = conn.cursor()
cursor.arraysize = 10000

batch_size = 10000
last_id = 0
data = []

while True:
    sql = """SELECT name_employer, id
             FROM my_table
             WHERE section = 'OTHER' AND id > :last_id
             ORDER BY id
             FETCH FIRST :batch_size ROWS ONLY"""
    cursor.execute(sql, {'last_id': last_id, 'batch_size': batch_size})
    batch_rows = cursor.fetchall()
    if not batch_rows:
        break
    data.extend(batch_rows)
    # 更新last_id为当前批次最后一条数据的id
    last_id = batch_rows[-1][1]

cursor.close()
conn.close()

3. 用更底层的批量API减少内存开销

如果数据量实在太大,还可以结合numpy直接把数据读取到数组里,减少Python对象创建的开销,速度会更快:

示例代码:

import cx_Oracle
import numpy as np

conn = cx_Oracle.connect("用户名/密码@数据库地址")
cursor = conn.cursor()
cursor.arraysize = 100000

sql = """SELECT name_employer
         FROM my_table
         WHERE section = 'OTHER'"""

cursor.execute(sql)
# 根据字段类型调整dtype,比如这里假设name_employer是字符串类型
data = cursor.fetchall_array(np.dtype("U100"))

cursor.close()
conn.close()

额外优化建议

  • 确保section字段有索引,这样数据库过滤数据的速度会快很多
  • 如果不需要把所有数据都存在内存里,直接边读边处理(比如写入CSV、写入其他数据库),避免内存不足拖慢速度
  • 只查询需要的字段,别用SELECT *(你原代码已经做到了,继续保持)

内容的提问来源于stack exchange,提问作者Sang Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:55:23