咨询一个组合索引的使用问题

为提高效率,提问时请尽量提供详细背景信息,问题描述清晰可优先响应。以下信息点请尽量提供:

  • 系统版本 & kernel 版本
  • TiDB 版本
  • 磁盘型号
  • 集群节点分布
  • 数据量 & region 数量 & 副本数
  • 【**问题描述( 最近阅读了tidb的官方文档,也搜索了一些有关group by,组合索引之类的文档。我们有一个需求,所以可以对上这个问题,举个例子,百亿级别的数据,场景如下,怎么建索引呢? select sum(pv),user_id,city,product_id,entity_id,sub_id,time_num from tb_pv where user_id = ‘’ and city = ‘’ and product_id = ‘’ and sub_id = ‘’ and entity_id in () and time_num between ‘20191001’ and ‘20191101’ group by entity_id,time_num order by … limit ;

说明一下,time_num是一个表示时间区间的,比如可以用20191001代表19年10月1日,在数据为中每一行都已经存放了一个汇总的值,需求是二次汇总。 这种情况下该怎么建组合索引呢? where条件中会用到范围,group by中也用到了一些字段,如果建组合索引,where 和group 中用到的字段应该用什么顺序? 此外,是不是也存在过滤性强的字段要放在组合索引左边,且我的where条件中的in和between两个范围查询只能有前一个用到索引的情况? 是否需要建多个组合索引呢?需要的话要怎么建呢,谢谢help,没有在官网找到相应的解释,就来此问了。

)**】

  • 关键词

这类 SQL 没有标准答案,和你讨论下思路吧:

1,首先 in 和 between 都是范围查询,及时这两个列存在组合索引下,也只能二选一;

2,基于第一点,这个 SQL index reader(索引覆盖)是实现不了的,大概率需要回表,所以索引的主要作用是进行 filter、或者排序;

3,基于第二点,我们选择索引就变成确认下那些条件或者条件组合是过滤强,看上去 user_id = ‘’ and city = ‘’ and product_id = ‘’ and sub_id = ‘’ 这个是强条件,然后后面 entity_id、 time_num 二选一,还是看过滤性谁强,然后和前面的列在一起,进行组合索引,组合索引顺序就你说的,过滤性强的在左边,顺序查询的放最后。

谢谢,那么针对一条sql多范围查询,我只能选择过滤大的留用了。另外还有一个group by的问题。 如果索引列是a,b,c 那么where a = ‘’ and b = ‘’ group by c应该是可以用到a,b,c这个组合索引的。如果where a = ‘’ and b in () and c in () group by b,c呢? b和c可能就是上面的entity_id和time_num,我们关心的优化点其实有二,一是过滤时是否用到索引,二是分组聚合时是否用到索引。 这种情况,聚合时能用到索引吗?

@cugb 两个问题的回答:

  1. 过滤是能用到索引的,但是是索引的范围查才会比较有效,in 在某些情况下也会走范围查。
  2. 聚合能用到索引,只是它用索引的意义在于做 stream 聚合,一般只在需要 order by 的情况下才会走到索引上去。

组合索引,在where和group by中的使用顺序是怎样的,where a = ‘’ and b in () and c in () group by b,c 能否用到a,b,c这个组合索引呢。 谢谢回复

用不了,因为 (b,c) 不是 (a,b,c) 的前缀,相当于用 (a,b,c) 的索引不能保证 (b,c) 的顺序。