连载中 8/20

中间件之下:SQL 改写、归并与执行的流水线

2026-07-22 · 1377 阅读 · 0 评论 · 0 赞

透明之下不透明

上一篇文章里那句「业务代码一行没变」,是 ShardingSphere 这类中间件最大的卖点,也是最大的误会来源。应用看到的透明,是中间件在底下做了一大堆改写换来的。一条 SQL 从进来到结果返回,实际经过五个工位:解析、路由、改写、执行、归并。这篇把这五个工位各拆开看一眼——不要求你会造轮子,但要求你能在出问题时知道去哪儿查。

工位一二三:解析、路由、改写

解析把 SQL 文本变成语法树,认出表名、WHERE 条件、ORDER BY、LIMIT 各在哪儿;路由拿分片键的值代入规则,算出这条 SQL 该去哪些分片——带 user_id = 9527 的查询被精确路由到一个库一张表;不带分片键的,路由结果是「全分片」(广播)。改写最容易出幺蛾子:逻辑 SQL 要变成物理可执行的语句,除了把 t_order 换成 t_order_2,还有两类隐蔽改写:

逻辑:  select * from t_order where user_id=9527 limit 100000,10
改写:  select * from t_order_2 where user_id=9527 limit 0,100010
        // limit 起点被抹平:跨片分页必须重算,第 10 篇展开

逻辑:  select avg(amount) from t_order_2 ...
改写:  select sum(amount) as AVG_DERIVED_0, count(amount) as ...
        // avg 不能跨分片求平均,先带出 sum 与 count

看到执行日志里凭空多出的 AVG_DERIVED、被改大的 limit,不要慌——那是改写工位的正常输出。

工位四:并发执行

改写后的物理 SQL 发往各目标分片。精确路由只有一条 SQL、一个连接,快得像没分过片;广播路由则是几十条 SQL 并发打到几十张表——每个分片各自利用索引是快的,但整体耗时取决于最慢的那个分片,而且连接数、内存占用瞬间翻几十倍。这也是为什么「尽量带分片键」是分片系统的第一铁律:它不只是快慢问题,是资源占用方式的问题。

工位五:结果归并

各分片的返回集要拼成一个结果集还给应用,归并策略按场景分三种。遍历归并:单分片结果直接拼接,最便宜;排序归并:ORDER BY 的查询,各分片返回的是各自有序的流,用多路归并(每次从各流头取最小)拼出全局有序,内存友好;聚合归并:count 与 sum 把各分片的值相加,max 与 min 在流里选极值,avg 则靠改写阶段带出的 sum 与 count 在归并时重新相除——直接对各分片的 avg 求平均是错的,这就是改写阶段那个诡计的原因。分组聚合(GROUP BY)最贵:要先按分组键归并再聚合,分片多了内存与耗时都显著上涨。

理解流水线的实用价值

把五步流水线装进脑子,排查问题就有了地图:数据写错了地方——查路由(分片键取值与规则);查询莫名变慢——查路由结果是不是广播了;聚合结果不对——查改写与归并(尤其 avg);分页越翻越慢——那是 limit 改写与归并的固有代价,第 10 篇给解法。中间件的透明是承诺,不是魔法——知道玻璃后面在干活的人是谁,玻璃碎了才知道找谁

流水线的两个工位——聚合归并与分页归并——代价最重,值得各花一篇展开。下一篇先讲跨分片聚合与排序的归并账本。

503

10 年全栈工程师 · 503咖啡馆主理人

#SQL改写#结果归并#多路归并#聚合归并#分片中间件

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞