不支持语法
select
跨分片的交叉查询,两个表中的分片字段不同
跨结点的联合查询
insert
插入的字段不包含分片字段
插入的分片找不到对应的分片
复制插入,insert into ... select ...
update
更新列包含分片列
delete
删除语句不能起别名,delete user_info a where a.main_user_id=1
全表扫描
1、复杂的sql会分发到所有库上执行,并且在mycat中进行比较、合并,要尽量避免。
2、insert/replace 必须要包含分库字段
3、select/update/delete语句如果where没有包含分库字段,会进行全表扫描。
4、支持in(...)语法,mycat 内部将其视为多个条件值的OR。
聚合函数
1、如果目标表分库,mycat可以支持任何聚合函数,实际上DRDS 是直接把原sql 传递到后端mysql 执行
2、sql语句经过mycat路由后,直接发送到后端单个mysql 库上执行。如分库字段在where条件中都是= 关系,同样可以支持任何聚合函数。
3、全表扫描:目前支持聚合函数有:count,max,min,sum 另外在全表扫描时同样支持like,order by,limit ,不支持group by。
1、count
select *,count(*) 不支持,需要把前面的* 展开成具体的列名
select count(*)+1 不支持,不要把count 进行二次运算
2、order by
1)order by 中出现的列名,保证在select 后出现,
如:select c1 from tb order by c2 写成:select c1,c2 from db order by c2
2)当语句中同时有order by 和 limit 分页时,mycat 执行order by 的内部逻辑是将所有的limit offset 之前的数据从mysql 加载到mycat 服务器内存中进行排序。所以不要对大量数据进行order by + limit 翻页。
3、对于非count,max,min,sum的聚合函数,在全表扫描的场景下执行不一定会返回错误,但是执行的结果很可能是错误的。
4、mycat 支持like 查询,会进行全表扫描
mycat 的HINT支持
mycat 对自身不支持的sql 语句提供了一种解决方案,即在要执行的sql 语句前添加额外的一段注解sql,这样sql 就能正确执行,这段sql 称为“注解sql”。其作用就是通过“注解sql”找到最终执行的sql数据节点,把要执行的sql发送到节点执行。
使用方式:/*!mycat:sql=注解sql*/要执行的sql
示例:
前提:表tb_user 分片字段为user_id。
操作:通过mysql 命令连接到 mycat(连接命令mysql -h192.168.192.133 -utest -ptest -P8066 -DTESTDB)
执行sql
mysql>select * from tb_user;
ERROR 1105 (HY000): backend connect: java.net.NoRouteToHostException: No route to host
可以看到错误信息为找不到目标host
使用注解,查询某一个结点的所有tb_user 数据,查询user_id=227 上分片的所有user_id,使用注解如下:
mysql>/*!mycat:sql=select 1 from tb_user where user_id=227*/select user_id from tb_user;
注解查询出来的数据在那个结点,就把sql 发送到那一个结点执行并返回。
select
跨分片的交叉查询,两个表中的分片字段不同
跨结点的联合查询
insert
插入的字段不包含分片字段
插入的分片找不到对应的分片
复制插入,insert into ... select ...
update
更新列包含分片列
delete
删除语句不能起别名,delete user_info a where a.main_user_id=1
全表扫描
1、复杂的sql会分发到所有库上执行,并且在mycat中进行比较、合并,要尽量避免。
2、insert/replace 必须要包含分库字段
3、select/update/delete语句如果where没有包含分库字段,会进行全表扫描。
4、支持in(...)语法,mycat 内部将其视为多个条件值的OR。
聚合函数
1、如果目标表分库,mycat可以支持任何聚合函数,实际上DRDS 是直接把原sql 传递到后端mysql 执行
2、sql语句经过mycat路由后,直接发送到后端单个mysql 库上执行。如分库字段在where条件中都是= 关系,同样可以支持任何聚合函数。
3、全表扫描:目前支持聚合函数有:count,max,min,sum 另外在全表扫描时同样支持like,order by,limit ,不支持group by。
1、count
select *,count(*) 不支持,需要把前面的* 展开成具体的列名
select count(*)+1 不支持,不要把count 进行二次运算
2、order by
1)order by 中出现的列名,保证在select 后出现,
如:select c1 from tb order by c2 写成:select c1,c2 from db order by c2
2)当语句中同时有order by 和 limit 分页时,mycat 执行order by 的内部逻辑是将所有的limit offset 之前的数据从mysql 加载到mycat 服务器内存中进行排序。所以不要对大量数据进行order by + limit 翻页。
3、对于非count,max,min,sum的聚合函数,在全表扫描的场景下执行不一定会返回错误,但是执行的结果很可能是错误的。
4、mycat 支持like 查询,会进行全表扫描
mycat 的HINT支持
mycat 对自身不支持的sql 语句提供了一种解决方案,即在要执行的sql 语句前添加额外的一段注解sql,这样sql 就能正确执行,这段sql 称为“注解sql”。其作用就是通过“注解sql”找到最终执行的sql数据节点,把要执行的sql发送到节点执行。
使用方式:/*!mycat:sql=注解sql*/要执行的sql
示例:
前提:表tb_user 分片字段为user_id。
操作:通过mysql 命令连接到 mycat(连接命令mysql -h192.168.192.133 -utest -ptest -P8066 -DTESTDB)
执行sql
mysql>select * from tb_user;
ERROR 1105 (HY000): backend connect: java.net.NoRouteToHostException: No route to host
可以看到错误信息为找不到目标host
使用注解,查询某一个结点的所有tb_user 数据,查询user_id=227 上分片的所有user_id,使用注解如下:
mysql>/*!mycat:sql=select 1 from tb_user where user_id=227*/select user_id from tb_user;
注解查询出来的数据在那个结点,就把sql 发送到那一个结点执行并返回。
事物支持
没有跨分片的事物强一致性支持,单库内部可以保证事务的完事性。如果跨库事物,在执行的时候任何分片出错所有分片都会加滚,但是只要应用发起commit,不能保证所有的分片都能commit。