2.4 注解/Hint
Hint, 即注解。 我们定义为:在要执行的SQL语句前添加额外的一段由注解组织的代码,这样SQL就能按照编写者的意图执行,这段代码称之为“注解”。
注解的作用如下:
- 指定路由,比如强制读写分离。
- 帮助dble支持一些不能实现的语句,如单节点内存储过程的创建和调用,如insert…select…;
原理解释:分布式环境下执行SQL语句的流程是先进行SQL解析处理,计算出路由信息后,然后到对应的物理库上去执行;若传入的SQL语句无法解析,则不会去执行。注解则可以告诉解析器按照注解内的SQL(称之为注解SQL)去进行解析处理,解析出路由信息后,将真正要执行的SQL语句(称之为原始SQL)发送到对应的物理库上去执行。
2.4.1 Hint语法
Hint语法有三种形式:
- /*!dble:type=....*/
- /*#dble:type=...*/
- /* */(只适用于读写分离功能)
"/*#dble: */" for mybatis and "/*!dble: */" for mysql
具体语法介绍请见:Hint
其中,type有4种值可选:shardingnode,db_type,sql,db_instance_url。每一种值的功能和形式详见各个部分的具体说明。
2.4.2 类型shardingnode
- 形式
shardingnode=node
其中,node为单个数据节点名,不能为多值(node定义参见配置1.5 sharding.xml)。 - 功能
为不方便路由或者不能路由的的语句指定具体的目的数据节点。
2.4.3 类型db_type
- 形式
db_type=master或者db_type=slave - 功能
帮助实现正确的业务逻辑,强制读写分离。 - 注意事项
delete, insert, replace, update, ddl语句不能使用db_type=slave进行注解。
2.4.4 类型sql
- 形式
sql=sql_statement - 功能
用sql_statement的路由结果集作为实际sql语句的执行数据节点。支持存储过程。
2.4.5 类型db_instance_url
- 形式
类型db_instance_url=ip:port - 功能
在读写分离场景下,可直接下发到相应的mysql实例 - 注意事项
运行delete, insert, replace, update, ddl语句时需考虑mysql节点的read_only属性
2.4.6 注意事项
写注解需要注意如下事项:
- dble的注解和MySQL原生注解含义不同, 想通过MySQL原生注解来设置变量或者指定索引是无法得到预期结果的。如#1169
- 使用select语句作为注解SQL,不要使用delete/update/insert 等语句。 delete/update/insert 等语句虽然也能用在注解中,但这些语句在SQL处理中有一些额外的逻辑判断,会降低性能,不建议使用;
- 注解SQL 本身禁用表关联语句,注解目的是路由计算,如果本身写得过于复杂,会影响路由计算;
- 使用hint做DDL需要额外执行reload @@metadata
- 使用hint做session级别的系统变量和环境变量可能不会生效,请慎用
- 使用注解并不额外增加的执行时间;从解析复杂度以及性能考虑,注解SQL应尽量用最简单的SQL 语句,如select id from tab_a where id=’10000’;
- 能不用注解也能够解决的场景,尽量不用注解。
- 在读写分离场景下,语句为/ xxx /的注释(纯注释,不包含sql),uproxy会将该语句发往slave,dble会将该语句发往master。