今天下午有一个紧急需求,是辅助业务部门做一个紧急查询,既然说紧急查询,那么肯定业务上需要加急处理,那么很快就需要找到我们DBA来帮忙了。
需求的情况是,需要根据某一个用户的标识(比如手机号)来定位对应用户的id,可能同一个身份证号,可以注册多个不同的id。
根据数据的情况,在系统中已经做了分库分表。情况类似下面的形式。
比如说数据分成了12个用户,每个用户中都有一个account_delta的表,但是每个用户中的数据完全不同,然后每3个用户对一个物理数据库,所以基本就是4个分库,12个用户。
然后存在一个公共库的数据,这个部分也是一个概要信息,就是用户id的一个绑定关系,是放在了一个公共库中,也就意味着这个表没有做分库分表。
现在正如红色箭头所示,传入了对应的标识字段,需要做紧急查询,这就意味着需要在这4个分库12个用户中做一个全范围查询。
而且比较要命的提供的查询条件是非索引字段,那么只能做全表,所以12个用户一个一个来查,然后merge起来,人肉hadoop,实在是紧急处理不了。
这个时候可以参考的一个地方就是我们存在一个统计库,这个统计库中会定时同步这些账号库中的这部分数据,目前是采用增量刷新的方式,所以在统计库中的结构如下:
统计库中目前是创建了12个物化视图,和源库中的12个基表是类似的。然后对于开发同事来说,就是一个简单的account_delta,即一个简单的view。
在大多数的场景使用中没有碰到什么明显的性能问题。
所以这个问题就可以转化为下面的形式
这个时候这些查询就可以直接在统计库中完成,而不用一个一个库的去逐个尝试,因为目前统计库中的数据是一天一次增量刷新,如果觉得数据不够新,可以再做一次增量刷新即可。
所以这些工作都可以在统计库中完成,对于原本的这些分库没有任何的压力和负载。而且速度也是大幅度提高。
然后查到对应的用户id之后,需要再一次做一个关联查询,就是和公共库中的data_bind关联,得到最后需要的数据,这个data_bind在统计库中没有做同步,而且本身也没有做分库分表。
但是值得一提的是这个表中的用户id有对应的索引,所以在公共库中按照用户id来查询,性能也还是不错的。
然后就这样简单分析了问题之后,在统计库中查询,因为是全表扫描,然后再开个并行,分分钟就会得出结果,然后把返回的用户id和公共库的data_bind关联起来,很快就能得到最后的结果。
所以看似简单枯燥的日常问题处理,如果多一些改进思路,那么自己也会轻松许多。