TiDB 是否有办法实现类似 MySQL 流式的办法

select a,b,c,d,e,d... from table_name 
where update_time >= '2026-02-09 00:00:00' 
       and update_time < '2026-02-10 00:00:00'

类似这样的 sql,mysql 可以用流式处理,降低使用的内存,tidb 是不是不支持,这条 sql 会扫到 300w 条数据,tidb 的 tidb_mem_quota_query 改成 20GB 还是不行,tidb_server_memory_limit也会达到阈值,tidb 的内存将近打满也跑不出来,有什么办法吗

【TiDB 使用环境】生产环境 /测试环境
【TiDB 版本】6.5.8
【部署方式】k8s
【操作系统/CPU 架构/芯片详情】amd64
【机器部署详情】tidb 8C32G x2

1 个赞

TiDB 目前不直接支持 MySQL 那样的流式处理机制来降低内存使用。但对于处理大数据量查询导致的内存问题,有以下解决方案:

参数调整优化

  • 调整 tidb_mem_quota_query 参数:虽然您已将其设置为 20GB,但可以尝试将其设置为更大值,如 30GB 或 40GB

  • 开启临时磁盘存储:设置 tidb_enable_tmp_storage_on_oom=ON,允许算子在内存不足时使用临时磁盘存储

  • 调整内存阈值报警:设置 tidb_memory_usage_alarm_ratio 为较低值,提前预警内存问题

SQL 优化策略

  • 添加适当索引:确保 update_time 字段有索引,提高查询效率

  • 拆分查询:将 300 万条数据的查询拆分为多个小批次处理,减少单次查询的内存占用

  • 避免不必要的列:只选择必要的列,而不是使用 SELECT *

架构调整

  • 引入 TiFlash 列存引擎:将查询路由到 TiFlash 执行,性能可提升 20 倍以上

  • 使用分区表:按 update_time 进行分区,实现分区裁剪,只扫描必要的数据

  • 增加 TiDB 节点:扩展计算资源,提高整体处理能力

资源管理

  • 合理设置 tidb_server_memory_limit:根据服务器内存总量合理分配,避免单个实例内存压力过大

  • 配置资源隔离:确保该查询不会占用过多系统资源

监控与调优

  • 监控内存使用情况:通过 TiDB 面板监控内存使用,及时发现内存瓶颈

分析执行计划:检查 SQL 执行计划是否存在不合理的操作,如全表扫描等

1 个赞

32GB 内存存不下300w数据

# 使用 StreamingResult 流式获取执行结果

这条 sql 会扫到 300w 条数据,tidb 的 tidb_mem_quota_query 改成 20GB 还是不行

  1. TiDB 内存控制文档
  2. 检查表里是不是有大字段

tidb不支持MySQL利用read net buffer边查询边发送的的机制,需要全部数据加载到内存再发送吗??第一次留意到这个细节。

tidb_enable_lazy_cursor_fetch = on 就是数据库侧的流式吧?不过当前是实验特性

1 个赞

执行计划具体式怎样的啊

当然不会全部读到内存,要不怎么导出大表数据

MySQL 的流式处理(通过mysql_use_result而非store_result)是客户端逐行读取结果,服务端不缓存完整结果集;但 TiDB 作为分布式数据库,其执行架构(MPP 模型)决定了它“无法完全像 MySQL 一样做纯流式返回”。
TiDB 的计算节点(TiKV/TiFlash)会先在节点内做数据聚合 / 筛选,再将结果返回给 TiDB Server,这个过程中 TiDB Server 会缓存结果集,这也是你内存打满的核心原因。

1 个赞

在 TiDB 中,通过 JDBC 驱动的 StreamingResultCursor Fetch 机制,可以实现客户端流式拉取数据,避免一次性加载全部结果到内存。

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。