shardingsphere-proxy 的 hint 在 sql 解析失败时不会生效,因路由前必须完成解析;表名大小写需严格匹配;批量 insert 中 hint 仅作用于首行;默认关闭需显式启用 sql-comment-parse-enabled。

ShardingSphere-Proxy 的 SQL 解析失败时 Hint 不生效
SQL 解析失败,/*+ SHARDING_HINT_TABLE=xxx */ 这类 Hint 就不会被识别——因为 ShardingSphere-Proxy 在路由前必须先完成 SQL 解析,解析失败直接走默认逻辑或报错,Hint 根本没机会执行。
常见错误现象:java.lang.UnsupportedOperationException: Cannot support DML operation with multiple tables 或 UnsupportedSQLException,尤其出现在含子查询、CTE(WITH)、窗口函数或非标准别名的语句中。
- 优先确认 SQL 是否能被 ShardingSphere 自带的 SQL 解析器支持:用
SELECT 1、INSERT INTO t VALUES (?)等简单语句测试,再逐步加复杂度 - ShardingSphere-5.3.2+ 默认使用
SQL92解析器,对 MySQL/PostgreSQL 扩展语法兼容有限;若业务重度依赖 MySQL 特性(如INSERT ... ON DUPLICATE KEY UPDATE),需显式配置sql-show: true并观察日志里的Actual SQL是否出现,没出现就说明卡在解析阶段 - 绕过解析限制的临时办法:把复杂逻辑拆到应用层,Proxy 层只做单表路由;或改用
sharding_hint+set sharding_hint_table = 'xxx'的会话变量方式(但仅对 DML 有效,且需客户端保持连接)
Hint 强制路由到指定分片时表名大小写不匹配
MySQL 默认忽略表名大小写,但 ShardingSphere-Proxy 的 Hint 路由是严格字符串匹配——/*+ SHARDING_HINT_TABLE=user_info */ 和实际逻辑表名 USER_INFO 或 User_Info 不一致,就会路由失败,查不到数据或写入错误分片。
使用场景:多环境(开发/测试/生产)间逻辑表命名风格不统一,或 DBA 建表时用了大写,而应用代码里写的是小写。
- 检查
schema.yaml中tables下定义的逻辑表名,确保与 Hint 中写的完全一致(包括下划线、大小写) - MySQL 配置项
lower_case_table_names=1不影响 Proxy 的 Hint 匹配逻辑——Proxy 不读这个参数,它只认你配置里写的和 Hint 里写的是否字面相等 - 如果无法统一命名,可在
props:下开启sql-comment-parse-enabled: true(5.3.0+),并改用更健壮的注释格式:/* ShardingSphere hint: sharding_hint_table=user_info */(注意无加号、空格敏感)
Hint 在批量 INSERT 或 REPLACE 场景下只作用于第一条记录
ShardingSphere 对批量语句(INSERT INTO t VALUES (1),(2),(3))的 Hint 处理有局限:它只提取第一条记录对应的分片值,后续记录沿用相同路由结果,不重新计算——这在分片键值不同时会导致数据错乱。
性能影响明显:看似用了 Hint 强制路由,实际部分数据进了错误分片,查不出来,还难以排查。
- 批量插入必须保证所有行的分片键值相同,否则不要依赖 Hint;应改用单条
INSERT+ 多次执行,或改用sharding_hint会话变量(SET sharding_hint_database = 'ds_1'; SET sharding_hint_table = 't_order_0') -
REPLACE INTO本质是DELETE + INSERT,ShardingSphere 会尝试解析为两条语句,Hint 只绑定在 INSERT 段,DELETE 可能路由到别的分片,造成数据残留 - 5.4.0 开始支持
sharding_hint的事务级作用域,建议在事务开头SET,结尾RESET,比注释 Hint 更可靠
ShardingSphere-Proxy 启动后 Hint 不生效却无报错
最常被忽略的一点:Hint 功能默认关闭。即使配置了 props:,没显式启用 sql-comment-parse-enabled,所有 /*+ ... */ 注释都会被原样透传给后端数据库,Proxy 完全无视。
验证方法:开 sql-show: true,执行带 Hint 的语句,看日志里有没有 Actual SQL 行——没有就说明解析/路由根本没触发。
- 必须在
conf/server.yaml的props:下添加:sql-comment-parse-enabled: true(5.3.0+)或sql-show: true(用于调试,非必需) - 旧版本(5.2.x)用的是
sql-comment-parse-enabled,5.3.x+ 改为sql-comment-parse-enabled,拼写差一个字母就会静默失效 - 修改配置后必须重启 Proxy,热加载不生效;且要确认
schema.yaml中对应逻辑库启用了sharding规则,纯replica-query库不处理任何 Hint
Hint 的边界很清晰:它不是万能路由开关,而是解析成功后的“最后一公里”控制。一旦 SQL 结构超出解析器能力,或配置漏了一处小开关,它就彻底隐身——这种失效没有报错,只有数据不对,查起来最费时间。











