单条业务 SQL,在 TiDB 客户端直接执行耗时约 100ms,应用 JDBC 调用执行耗时 10s~300s,升级前应用执行耗时稳定 300ms 以内,升级后性能劣化严重。
从 SQL 执行耗时明细观测:慢查询集中在pipeline_queue_wait、fetch and wait、min_local_stream、max_local_stream几项等待耗时偏高,执行计划本身无大变化。
已做排查
主机资源指标全部空闲,排除硬件资源瓶颈;
对比库内直连与应用执行,差异仅客户端链路;
怀疑 v8.5.1→v8.5.6 版本中 LocalStream、结果集流式推送、Pipeline 调度逻辑改动,和 JDBC 驱动参数不兼容。
除驱动参数外,还有哪些会话变量、集群参数能够优化此类结果集拉取阻塞问题?
- 驱动层面:驱动版本偏低,与新版流式返回逻辑不兼容。
- 代码层面:fetchSize 配置不合理、游标使用不当,逐行频繁拉取。
- 应用框架:ORM / 连接池预读逻辑与 TiDB 下发机制冲突。
- 链路网络:TCP 小包过多、链路延时波动。
可调整tidb_enable_local_stream、tidb_streaming_fetch_batch_size、tidb_pipeline_dml、tidb_plan_cache等会话 / 集群变量关闭或调优流式、流水线、缓存相关特性,快速缓解结果集拉取阻塞。
主要看三点:数据量级、一致性要求、运维能力。数据量超过单机 MySQL 瓶颈、需要强一致分布式事务的,TiDB 是成熟方案。如果只是几千亿条数据跑分析,也可以考虑 ClickHouse。
8.5.x 中间版本重构 LocalStream 本地流式缓存、Pipeline 执行流水线、DistSQL chunk 推拉逻辑,新版默认队列深度、缓冲区、调度粒度收紧,JDBC 游标分批 (fetchSize 小 + useCursorFetch=true) 场景出现上下游速率不匹配:TiKV 推数据 > TiDB 本地 LocalStream 消费 > JDBC 客户端拉取,数据在 LocalStream/pipeline 队列积压 → min/max_local_stream、pipeline_queue_wait、fetch and wait 暴涨;MySQL 客户端全量拉取无游标,不触发分批阻塞,所以本地执行 100ms、JDBC 十几秒**。
这个问题其他人也遇到过。
是不是有些参数不兼容
要比较的话得看系统瓶颈在哪。MySQL 是单点写入瓶颈,TiDB 通过 Raft + Region 分片解决。但分布式一致性开销(多数派写入)在跨 AZ 部署时延迟会更明显。关键还是业务场景匹配。
有时候,升级 TiDB 后可能会引入一些未知的兼容性问题或 bug。
选型要看具体场景。如果数据量在百TB以内、读多写少、对强一致性有要求,TiDB 挺合适。如果数据量级不大(单机够用)或业务逻辑复杂(存储过程、触发器多),MySQL 更省事。建议拿业务做 POC 测试对比。
数据量级、一致性要求、运维能力
JDBC 驱动参数优化可以试一试