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

在Jupyter Notebook中从MySQL高效提取1亿条数据的技术咨询

优化Jupyter Notebook中MySQL 1亿条数据的分批提取方案

嘿,兄弟!你选分批提取的思路完全正确——1亿条数据一次性拉取肯定直接把内存干爆,用pymysql分批处理是最稳妥的方向。我帮你把这个方案补全,还加几个关键优化点,让你拉数据更快更稳:

核心优化思路:用主键范围分页替代OFFSET

用LIMIT ... OFFSET ...在数据量到千万级之后会越来越慢,因为数据库得先扫描前面所有的行再返回结果。换成基于主键的范围查询,效率会高很多,前提是你的表有自增主键(比如id)或者唯一的有序字段。

完整可运行的分批提取代码

import pymysql.cursors
import pandas as pd

# 数据库连接配置
db_config = {
    'host': 'XXX',
    'user': 'XXX',
    'password': 'XXX',
    'db': 'XXX',
    'charset': 'utf8mb4',  # 建议用utf8mb4兼容emoji等特殊字符
    'cursorclass': pymysql.cursors.SSCursor  # 流式游标,不一次性加载所有结果到内存
}

# 分批大小,根据你的Jupyter内存调整,建议1w-10w条/批
batch_size = 10000
# 存储所有数据的列表
all_data = []

try:
    # 建立连接,关闭自动提交减少开销
    connection = pymysql.connect(**db_config)
    connection.autocommit(False)
    
    with connection.cursor() as cursor:
        # 先获取主键的最小和最大值,确定查询范围
        cursor.execute("SELECT MIN(id), MAX(id) FROM your_table_name")
        min_id, max_id = cursor.fetchone()
        
        current_id = min_id
        while current_id <= max_id:
            # 用主键范围查询,避免OFFSET的性能问题
            query = """
                SELECT col1, col2, col3  -- 只取需要的字段,别用SELECT *
                FROM your_table_name
                WHERE id >= %s AND id < %s
            """
            cursor.execute(query, (current_id, current_id + batch_size))
            
            # 批量获取当前批次的数据
            batch_data = cursor.fetchall()
            if not batch_data:
                break
            
            # 转成DataFrame(如果需要)或者直接处理
            df_batch = pd.DataFrame(batch_data, columns=['col1', 'col2', 'col3'])
            all_data.append(df_batch)
            
            # 更新下一批的起始主键
            current_id += batch_size
            print(f"已提取 {current_id - min_id} 条数据...")

    # 合并所有批次的数据
    final_df = pd.concat(all_data, ignore_index=True)
    print(f"数据提取完成,总条数:{len(final_df)}")

finally:
    # 确保连接关闭
    if connection:
        connection.close()

几个关键优化点

  • 流式游标(SSCursor):默认游标会把整个查询结果加载到内存,SSCursor会逐行获取,内存占用极低,适合超大批量数据
  • 关闭自动提交:批量操作时关闭autocommit,减少数据库的提交开销
  • 只查询需要的字段:别用SELECT *,只取你需要的列,减少数据传输量和内存占用
  • 主键范围分页:相比OFFSET,这种方式利用主键索引,查询速度不会随着数据量增大而下降
  • 调整分批大小:如果Jupyter内存足够,可以适当调大batch_size(比如5w或10w),减少循环次数;内存紧张就调小

额外建议

如果你的表没有自增主键,可以用其他有序的唯一字段(比如时间戳create_time)来做范围分页,但要确保该字段有索引,否则查询速度还是会慢。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:20:36