DRDS SQL使用规范 方案正文 insert操作 insert写法规范 不建议逐条insert,推荐使用insert into values (),()..();语法。 MySQL的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现批量插入。MySQL JDBC驱动在默认情况下会无视executeBatch()语句,把预计批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,批量插入实际上是单条插入,直接造成较低的性能。只有把rewriteBatchedStatements参数置为true, 驱动才会批量执行SQL。另外这个选项对INSERT/UPDATE/DELETE操作都有效。 拆分字段的值:不建议使用函数、表达式、子查询等,推荐使用常量值。 普通字段的值:不建议使用子查询,推荐使用常量、函数、表达式。 大批量数据导入 推荐使用loaddata local infile来实现大批量数据导入。 数据迁移场景 建议使用mysqldump导出sql文件,再使用mysql source命令导入。 autoincrement字段 DRDS使用Sequence来实现autoincrement语义,并保证全局唯一。 赋值:若使用autoincrement字段,建议不要在values子句中赋值,否则容易造成主键冲突。如果在values中赋了值,建议使用alter sequence语句更改。 步长:autoincrement字段步长建议不要设置成1,会导致性能低下。默认设置成1000。 update与delete操作 普通更新 进行update/delete操作时,where条件建议带上拆分字段; 无法带上拆分字段的场景,建议控制并发度,控制更新/删除涉及的数据条数。建议先用select查出相应的数据,double check确保数据范围无误后再实行update/delete操作。 拆分字段更新 条数限制:DRDS拆分字段更新有数据量限制,一般不能超过10000条数据,数据量越少越好。若超过10000条数据,建议用改重建表的方式来做,或者是拆分成多次update操作来等价实现。 操作的时机:建议选择在业务低谷期做。 关联操作 不建议进行表关联更新、表关联删除操作,即不建议进行多张表同时进行update/delete操作。 子查询及limit操作 不建议update/delete语句中含有子查询。不建议update/delete语句中含有limit或order by limit语句。 select操作 Order by 及 Limit函数 "order by limit offset, count"场景,禁止给offset赋大数值,即禁止深度翻页。 Group by函数 不建议selectlist部分含有非group by列。 不支持不可下推的groupconcat聚合函数内含有order by子句。 不建议distinct、group by字段多于3项。 不建议join、或者子查询操作之后含有group by操作 不建议使用count(distinct ),sum(distinct )操作。 Join函数 select场景,建议join条件是每个表的拆分字段或使用广播表,或者是驱动表是一个小表(inner/left join驱动表是左表,right join驱动表是右表)。 不建议两个大表直接进行join操作。 不建议join on condition中含有非等值操作。 如遇到临时表超限(Temp table limit exceeded)报错,说明JOIN中间数据产生了临时表且超限,建议进行SQL调优。 不建议5张表以上进行join操作。 join查询操作建议不要开启事务。 不建议在事务中进行join查询,开启事务会影响DRDS对join算法的选择,无法使用最高效的算法。 子查询 不建议子查询包含在OR表达式中,或者是子查询的关联条件包含在OR表达式中 不建议使用含有limit的标量子查询,如 select (select x from t2 where t2.id t.id limit 1),a,b from t。 如果子查询和主表都路由到同一分片,建议在SQL前加/+dbxxx/来精准路由。 不建议子查询内部含有join语句。 不建议写嵌套子查询。 不建议ROW表达式跟子查询做比较操作,如 select from t where (a,b,c)(select x,y,z from t2 where …)。 不建议selectlist里面含有超过2个以上的子查询 。 DDL DDL执行时机 对已有表进行DDL操作时建议放在业务低峰期进行。 分片数 创建新拆分表时建议结合实际数据量进行合理预估,总分片数满足需求即可。不建议使用超出实际需求的分片数,拆分表分片数并非越多越好 高危DDL 进行高危DDL时请仔细校验SQL后谨慎操作,如DROP TABLE, TRUNCATE TABLE等操作。 DDL失败修复 DDL命令如遇报错,可以使用"check table 表名"命令对各个分片表结构进行校验,识别出失败的分片进行针对性修复。如ALTER TABLE命令遭遇失败可以在命令前添加/+allowalterreruntrue/,开启ALTER语句的幂等可重入执行后重试,直到check table 命令提示各个分片表结构达到一致则可认为执行成功。 MDL锁导致执行DDL报错 背景:为保证DDL的可用性,DRDS内部在执行DDL前会检查底层RDS相关表是否存在MDL锁。 若存在MDL锁,,则DDL会提前报错退出。 可能出现的问题:若系统中存在慢SQL,执行时间为几分钟不等,那么可能被MDL锁所阻拦,无法执行DDL。 解决方案1:在DRDS控制台提高参数“ddlprecheckmdlthresholdtime”的大小, 如提高到30分钟(1800秒)。 解决方案2:执行show metadata lock查看是否因为持有慢事务的MDL锁阻塞了DDL的执行。若存在阻塞, 可以使用kill physical threadId@host:port 来关闭底层慢事务。配合/+allowalterreruntrue /的hint, 以及check table来查看和执行,直到DDL彻底执行完。 DDL长时间卡死 在业务低峰期执行DDL时如果遇到长时间卡死情况,请另开会话执行xa recover命令查看是否有慢事务存在,如存在慢事务挂起请及时联系值班人员解决。