日、周、月维度是拆分成单独的表存储还是一张表存储
根儿上是一个写入和查询的权衡问题(存储压力其实可以忽略,因为周月维度数据量不大):
- 多张表:写入压力大、查询压力小;
- 一张表:写入压力小、查询压力大。
只能通过具体的案例来得到一个经验值:
- 数据量超过多大之后,适合用一张表,此时压力主要在写入上
- 查询性能要求多少,适合多张表,此时压力主要在查询上
案例分析:
卖家多维分析多张表
查询性能对比
- 通过单独的月表查询月维度
1 | # 消耗时间0.9s |
- 通过日表出月维度的数据
1 | # 消耗时间1.8s |
写入时间对比
- 单独的月表的导入任务的时间消耗
日表导入需要时间为:2.7小时,月表的导入时间:2.9小时,月表的导入时间是更长的
月表的导入数据量会更大一些,天表导入只需要60天,但是月表需要严格的2个月,配置的delta为60,但是真正对应的月份大多是3个月的情况。
- 单独的月表的存储空间的占用
天表占用空间:23G,月表占用空间4.1G,额外空间的占用确实可以忽略,因为即使是一张表,也需要创建rollup也需要消耗空间
卖家多维分析单张表
创建月分区表,dt维度通过创建rollup的方式来
1 | CREATE TABLE `app_invite_business_analysis_view_all` ( |
创建rollup
- rollup_cat3_dt( dt,bu_id,cat1_id,cat2_id,cat3_id,seller_id,bu_name,cat1_name,cat2_name,cat3_name,seller_name,customer_id,dt_customer_id,order_code,arranged_amt,coupon_amt,arranged_cnt,arranged_weight,billing_amt,bu_onshelf_sku_id,bu_arranged_sku_id,dt_bu_onshelf_sku_id,dt_bu_arranged_sku_id,ord_customer_str,quality_case_customer_str,sku_bu_id),
- rollup_sku_dt( dt,bu_id,cat1_id,cat2_id,cat3_id,cat4_id,seller_id,sku_id,bu_name,cat1_name,cat2_name,cat3_name,cat4_name,seller_name,sku_name,brand_name,sku_unit_desc,customer_id,dt_customer_id,order_code,arranged_amt,coupon_amt,arranged_cnt,arranged_weight,billing_amt,bu_onshelf_sku_id,bu_arranged_sku_id,dt_bu_onshelf_sku_id,dt_bu_arranged_sku_id,ord_customer_str,quality_case_customer_str,sku_bu_id),
- rollup_mo( mo_num,mtd_tag,dt,customer_id,dt_customer_id,order_code,arranged_amt,coupon_amt,arranged_cnt,arranged_weight,billing_amt,bu_onshelf_sku_id,bu_arranged_sku_id,dt_bu_onshelf_sku_id,dt_bu_arranged_sku_id,ord_customer_str,quality_case_customer_str,sku_bu_id),
- rollup_cat3_mo( mo_num,mtd_tag,bu_id,cat1_id,cat2_id,cat3_id,seller_id,bu_name,cat1_name,cat2_name,cat3_name,seller_name,dt,customer_id,dt_customer_id,order_code,arranged_amt,coupon_amt,arranged_cnt,arranged_weight,billing_amt,bu_onshelf_sku_id,bu_arranged_sku_id,dt_bu_onshelf_sku_id,dt_bu_arranged_sku_id,ord_customer_str,quality_case_customer_str,sku_bu_id),
- rollup_dt( dt,customer_id,dt_customer_id,order_code,arranged_amt,coupon_amt,arranged_cnt,arranged_weight,billing_amt,bu_onshelf_sku_id,bu_arranged_sku_id,dt_bu_onshelf_sku_id,dt_bu_arranged_sku_id,ord_customer_str,quality_case_customer_str,sku_bu_id)
数据导入
- 导入任务执行时间:2.6小时,但是导入的时间是下午,不是凌晨执行的,可能有偏差,但是感觉应该导入时间不是瓶颈
- 最终表的数据量:43G,数据范围为20210301到当天,天表和月表的数据范围为20210220到当天,天月表的总的数据量为28G;可以看出一张表的情况下(月分区,创建多个rollup的方式),数据量更大
数据查询
月维度查询对比
月维度的查询时间上没有差别,因为新表的分桶更合理,所以新表更快些
1 | SELECT t44926_0.`mo_num` `mo_num`, |
日维度查询对比
卖家表现查询:
- 天分区的表查询时间:0.5s(多次查询基本稳定这个时间)
- 月分区的一张表查询时间:0.9s、0.5s、0.6s、0.7s、0.5s,平均在0.7s左右
1 | SELECT t44926_0.`dt` `dt`, |
sku明细查询:
- 天分区表查询时间:3.7s、6s、4.3s、5s、3.9
- 月分区一张表查询时间:4.9s、4s、4.3s、3.9s、5s
1 | SELECT t44923_0.`dt` `dt`, |
总体表现:查询性能差距不是非常大,大查询在1s左右,小查询在200ms左右
总结&思考
感觉多张表的代价有点大,最好还是创建一张表,以月维度为分区,然后日、周的查询通过创建rollup来加速。
明细表的思考
从上面的性能测试可以看出,sku明细的查询基本需要5s开外了,比较慢,而且明细也是不需要聚合的,如果直接采用明细结果查询,是不是更快?
后续是不是考虑明细和类目粒度的分开存储?
1 | #不group by直接查询明细,只需要1.5s,如果使用es,性能应该会更好 |