①不支持分区,删除数据是个大坑。
解决方案:set @@session.tidb_batch_delete=1;
②插入数据太大也会报错
解决方案:set @@session.tidb_batch_insert=1;
但是需要注意的是set @@session.tidb_batch_insert=1; set @@session.tidb_batch_delete=1; 虽然一次插入、删除的记录变多了,但是它会破坏事务。底层的原理是将这批大数据切分成一小段一小段,每一小段没保证事务,但是整体并不保证事务
③ 删除表数据时不支持别名
delete from 表名 表别名 where 表别名.col = '1' 会报错
④ TIDB不支持GBK
⑤ TIDB 不支持存储过程
⑥创建完成一张数据表后,修改操作非常困难,有很多限制条件,可能也和分布式相关,不允许同时操作多个列,建议最好就把表的结构定义好,修改不要太频繁。
不支持同时创建多个索引
不支持同时创建多个列
不支持删除主键列或索引列
不支持修改索引
一次只能修改一列
⑦ TIDB列数支持太少,目前只支持500列,和oralce/mysql的1000列少太多(Oracle 最大列数为 1000;MySQL对于每个表具有4096个列的硬限制, 其中InnoDB每个表的限制为1017列, 最大行大小限制为65,535字节)
⑧查询优化
TiDB 的优化分为基于规则的优化(Rule Based Optimization)和基于代价的优化(Cost Based Optimization), 本质上 TiDB 的 SQL 引擎更像是一个分布式计算框架,对于大表的数据因为本身 TiDB 会将数据分散到多个存储节点上,能将查询逻辑下推,会大大的提升查询的效率。
TiDB 基于规则的优化有:
-
谓词下推
谓词下推会将 where/on/having 条件推到离数据表尽可能近的地方,比如:
select * from t join s on t.id = s.id where t.c1 < 10;
可以被 TiDB 自动改写成
select * from (select * from t where t.c1 < 10) as t join s on t.id = s.id;
2 关联子查询消除
关联子查询可能被 TiDB 改写成 Join,例如:
select * from t where t.id in (select id from s where s.c1 < 10 and s.name = t.name);
可以被改写成:
select * from t semi join s on t.id = s.id and s.name = t.name and s.c1 < 10;
3:聚合下推
聚合函数可以被推过 Join,所以类似带等值连接的 Join 的效率会比较高,例如:
select count(s.id) from t join s on t.id = s.t_id
可以被改写成:
select sum(agg0) from t join (select count(id) as agg0, t_id from s group by t_id) as s on t.id = s.t_id;
4:基于规则的优化有时可以组合以产生意想不到的效果,例如:
select s.c2 from s where 0 = (select count(id) from t where t.s_id = s.id);
在TiDB中,这个语句会先通过关联子查询消除的优化,变成:
select s.c2 from s left outer join t on t.s_id = s.id group by s.id where 0 = count(t.id);
然后这个语句会通过聚合下推的优化,变成:
select s.c2 from s left outer join (select count(t.id) as agg0 from t group by t.s_id) t on t.s_id = s.id group by s.id where 0 = sum(agg0);
再经过聚合消除的判断,语句可以优化成:
select s.c2 from s left outer join (select count(t.id) as agg0 from t group by t.s_id) t on t.s_id = s.id where 0 = agg0;
5:基于代价的优化有:
1. 读取表时,如果有多条索引可以选择,我们可以通过统计信息选择最优的索引。例如:
select * from t where age = 30 and name in ( ‘小明’, ‘小强’)
2. 对于包含 Join 的操作,我们可以区分大小表,TiDB 的对于一个大表和一个小表的 Join 会有特殊的优化。
例如 select * from t join s on s.id = t.id,优化器会通过对表大小的估计来选择 Join 的算法:即选择把较小的表装入内存中。
3. 对于多种方案,利用动态规划算法选择最优者,例如: (select * from t where c1 < 10) union all (select * from s where c2 < 10) order by c3 limit 10。t 和 s 可以根据索引的数据分布来确定选择索引 c3 还是 c2。
⑨:分页查询用唯一索引id顺序查询代替 id> xxx
官方建议用唯一索引而非唯一主键