EXPLAIN SELECT * FROM t_order WHERE order_no = '202611140001';
/* 路由日志里出现 broadcast=true targets=ds_00..ds_15 */

订单详情页按 order_no 精确查一条,网关日志里这条请求在 0.3 秒内发到了 16 个分片,每片返回 0 到 1 行,最终耗时 480 毫秒。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:分片键选的是 user_id,路由算法只认这一个字段,条件里没有它就推不出落哪个片。中间件只能把 SQL 原样发给所有片再合并,片数越多代价越大。

围绕「分片键与查询条件」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

处理上按这个顺序:先看中间件的路由日志 确认 SQL 有没有带分片键;把 order_no 和 user_id 的对应关系冗余到订单表 详情页按用户维度查;确实要按订单号查 单独建一张 order_no 到分片的映射表;把广播查询数量接进监控 超过阈值告警。

确认没问题再收工,同一条详情请求只落到一个分片 耗时回到 30 毫秒以内。

作者 9823189