TIDB问题记录

本文总结了TiDB数据库在数据操作和查询优化方面的一些常见问题及解决方案。包括不支持分区删除、批量插入可能导致事务破坏、不支持别名删除、不支持GBK编码、不支持存储过程等。此外,还探讨了TiDB的查询优化策略,如谓词下推、关联子查询消除、聚合下推等,并提到了分页查询的最佳实践。对于数据库管理员和开发者来说,了解这些技巧对于提升TiDB的使用效率至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

①不支持分区,删除数据是个大坑。

     解决方案: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 基于规则的优化有:

  1. 谓词下推

                    谓词下推会将 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

官方建议用唯一索引而非唯一主键

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值