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

无需生成CSV文件 如何将SQL大表数据直接读取到pandas中

问题结论

650万行7列的表完全可以一次性读取到pandas中,你的服务器64GB内存远高于该表的实际内存占用需求,内核崩溃是不合理的代码写法和默认参数导致的内存峰值溢出,调整参数即可实现需求。

问题诱因分析
  • 冗余执行了两次全表查询:你预先执行了result = engine.execute(query),已经将全表结果集缓存在了连接内存中,后续read_sql_query又重复执行了一次全表查询,相当于同时在内存中加载了两份数据,直接推高了内存峰值。
  • 默认参数导致内存浪费:pandas读取Oracle数据时默认会用高内存占用的数据类型存储(比如默认用int64/float64存储数值、用object类型存储字符串),同时默认的fetch数组大小较小,读取过程中反复申请内存会产生额外的内存开销。
  • 多余的连接池配置:你设置了pool_size=50,单查询场景下不需要这么大的连接池,多余的连接会占用不必要的内存空间。
优化代码方案

首先确认你使用的是64位版本的Python和pandas,32位Python有最大2GB的内存寻址限制,无法满足需求。

优化后的代码如下:

import pandas as pd
from sqlalchemy import create_engine

cstr = 'oracle://{user}:{password}@{sid}'.format(
    user=user,
    password=password,
    sid=sid
)

# 调整连接参数,缩小连接池,设置全局fetch数组大小
engine =  create_engine(
    cstr,
    convert_unicode=False,
    pool_recycle=10,
    pool_size=1, # 单查询场景只需要1个连接即可
    echo=True,
    arraysize=10000 # 调整单次fetch的行数,减少内存申请次数
)

query = 'Select * From Table'

# 读取时指定dtype减少内存占用,可根据你的表实际字段类型调整
# 示例:如果有3个数值列、4个字符串列,可按如下方式指定
df = pd.read_sql_query(
    query, 
    engine,
    dtype={
        "数值列1": "int32", # 如果数值范围小于2^31,用int32比int64省一半内存
        "数值列2": "float32", # 精度要求不高的浮点数列用float32
        "字符串列1": "string", # 用pandas StringDtype比object省内存
        "字符串列2": "string",
        # 剩余字段同理配置
    }
)
可选验证操作

你可以先在Oracle中执行如下SQL,确认表的实际磁盘占用大小,正常情况下650万行7列的表磁盘占用不会超过10GB,加载到内存后也不会超过20GB,完全适配64GB内存:

SELECT SUM(BYTES)/1024/1024 AS TABLE_SIZE_MB 
FROM USER_SEGMENTS 
WHERE SEGMENT_NAME = '你的表名(注意大写)';

内容的提问来源于stack exchange,提问作者YTE 1008

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:27:03