表优化&索引优化咨询

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:3.1
  • 【问题描述】:这样的表结构和索引,如何提升查询效率

背景: 有一个日志表,日增1亿。
表结构, 主要3个字段
| id | customer_id | device_id |
id是基于雪花算法生成的,按时间粗略递增
customer_id 表示客户id
device_id 是设备

索引:1、id主键索引 2、customer+device联合索引

目前有一个查询问题是 : 日新增的80%来自某2个大客户数据,其他数据较少。
sql: select id, device_id, receive_time from xxx where id < 141021042096209919 and id > 139907782278119424 and customer_id = ‘xxxx’ order by id desc limit 0,50;

这样的sql会被解析成按id索引扫描数据,直到满足50个。如果被大客户的热点数据淹没,目标数据的id会相对靠后,就比较慢了。
目前的解决办法是非大客户数据强制使用联合索引查询,效果会好一些。
但不知道有没有什么设计上改进办法

像这样的情况,应该如何优化。 是需要把大客户的数据单独分出来吗,分表?分区? 还是索引设计上可以有什么改进 TiDB的初衷好想不希望我们分库分表。

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出打印结果,请务必全选并复制粘贴上传。

  1. 当前小用户强制先走联合索引,再走id,应该是比较合理的
  2. 大客户,先走 id ,再走 cutomer 也是合理的。

当前是觉得哪个不满足业务要求,时间太久了吗?

不懂是不是有什么设计或者架构上的优化 比如说,需要按客户分数据吗,分片? 这样就不会干扰了

毕竟走联合索引在后期可能还是会有局限

你好,

id 是否对实际业务有明确意义,如果针对客户, customer_id 应为唯一索引,将从此表拆分,设立单独的 customer 客户表,设备如果与客户是多对一的关系,可以使用 left join 来查找设备。

可行的内部优化是将 两个 index 的结果merge到一起,减少数据扫描量。具体来说,根据 index 2 找到 id,然后再根据 index 1 筛选合格的 ID,这样两个索引综合考虑可以减少数据扫描量。这个优化我们正在考虑。如果可以的话,请提供具体的建表语句,scheme,部分数据,或者stats,方便我们内部构造实验场景。谢谢。

1 个赞

id只是粗略表示时间 目前还没有涉及跨客户查询和事务,我也有想法拆分,不过不能保证后续会涉及跨客户的事务和查询 联合索引的初衷是为了快速查询设备相关信息。如果只有客户索引,通过join查询设备数据,还会高效吗

@fzhedu 为我们的研发童鞋,

@tianyu4552 看下是否配合下提供上述信息,方便我们继续优化。

希望可以通过实验结果当做结论,我的理解是可以的,id 的 scan 我认为是没有意义的。

鉴于实现 index merge 的周期较长,建议的方案有如下两个:

  1. 取决于 customer id 不同值有多少,如果不到 一千,建议按照 customer id 采用 partition table 存储,每个 customer 一个 partition;
  2. 如果 customer id 过多,建议将热点 customer 单独存储到另外的表,然后结果上 union 一起返回或者进行后续的操作。

十分感谢。我自己再看看

:ok_hand:

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。