ClickHouse_行业模块ClickHouse服务优化实战
1.行业底表基本数据统计
1.1 典型二级类目数据量统计与超时请求统计
2022-10-12至2022-11-15的总数据行数与对应的时间较长自定义请求,使用到的索引只有:secondIndId+terminal+shopType
| 二级类目 | 底表粒度 (sku+browerAcct) | 聚合表粒度 (sku) | 数据量缩减倍数 | 行业趋势 groupby datetime | 品牌榜单top10 groupby brand | 店铺榜单top10 groupby shop | 商品榜单top200 groupby sku |
|---|---|---|---|---|---|---|---|
| 女装1343 | 542134328 | 123311605 | 4.39645829 | 5.97s | 6.33s | 4.36s | 10.55s |
| 男装1342 | 606898996 | 153551059 | 3.952424685 | 5.21s | 7.144s | 5.1s | 13.12s |
| 饮料冲调1585 | 396352751 | 14614808 | 27.11994239 | 4.53s | 3.24s | 3s | 2.31s |
| 奶粉1523 | 145654211 | 3533643 | 41.21927739 | 2.56s | 1.47s | 4.23s | 4.97s |
| 灯饰照明9856 | 143318024 | 24340347 | 5.888084669 | 3.99s | 2.16s | 2.11s | 2.91s |
| 减肥塑身9193 | 3648896 | 384148 | 9.498672387 | 0.68s | 0.8s | 1.51s | 0.83s |
| 特医配方食品27992 | 3659201 | 154811 | 23.63656975 | 0.66s | 0.82s | 1.48s | 0.75s |
1.2 top20数据量的二级类目
| secondIndId | count |
|---|---|
| 1342 | 153551059 |
| 1343 | 123311605 |
| 12099 | 57374279 |
| 9858 | 55893288 |
| 1345 | 54457959 |
| 11842 | 49468349 |
| 11730 | 49372352 |
| 830 | 41721031 |
| 6745 | 40055769 |
| 12102 | 38226249 |
| 11731 | 37844022 |
| 11158 | 36543128 |
| 729 | 32773074 |
| 9857 | 32323407 |
| 15249 | 30765820 |
| 1583 | 29960139 |
| 1584 | 28067354 |
| 12147 | 26508877 |
| 9856 | 24340347 |
| 1381 | 23281586 |
2.行业底表优化方案
2.1 物化视图与projection方案
针对不同请求接口具体分析请求超时原因,采用不同的优化方案:
- 商品榜单:更改请求sql,改用二次聚合;
- 店铺榜单:新建聚合到店铺粒度的物化视图,日店铺数量27w;
- 品牌榜单:新建聚合到品牌粒度的物化视图,日品牌数量22w;
- 行业趋势:新建聚合到三级类目粒度的物化视图。
创建测试聚合表
1 | CREATE TABLE bc_online.ck_zh_industry_product_union_all_agg_jiazhengyang3 on cluster LFRH_CK_Pub_173 |
1 | CREATE TABLE bc_online.ck_zh_industry_product_union_all_agg_jiazhengyang3_d ON CLUSTER LFRH_CK_Pub_173 as bc_online.ck_zh_industry_product_union_all_agg_jiazhengyang3 ENGINE = Distributed('LFRH_CK_Pub_173', 'bc_online', 'ck_zh_industry_product_union_all_agg_jiazhengyang3', rand()); |
创建三级类目粒度projection
因为要基于该projection继续聚合,所以对去重指标只能使用uniqMerge()中间状态。
1 | alter table bc_online.ck_zh_industry_product_union_all_agg_jiazhengyang3 on cluster LFRH_CK_Pub_173 add projection ck_zh_industry_product_union_all_agg_jiazhengyang3_shop_agg |
查询测试sql
1 | select |
没创建projection的执行计划
1 | Expression ((Projection + Before ORDER BY)) |
创建了projection的执行计划
1 | Expression ((Projection + Before ORDER BY)) |
查询ck query日志查看sql执行情况,读取数据量、是否使用projection等
1 | SELECT |
查看ck projection系统表
参考文献:https://blog.csdn.net/qq_21383435/article/details/122357463
1 | SELECT |
查看ck进程
1 | show processlist |
结论
查询query日志查看sql执行情况
| type | query_duration_ms | read_rows | read_bytes | projections |
|---|---|---|---|---|
| QueryFinish | 2609 | 20818506 | 11747434199 | [‘bc_online.ck_zh_industry_product_union_all_agg_jiazhengyang3.ck_zh_industry_product_union_all_agg_jiazhengyang3_shop_agg’] |
| QueryFinish | 1094 | 116128739 | 105200969395 | [] |
从日志可以看出使用projection扫描数据量少了,但是查询时间反而变长了,然后ck引擎根据扫描数据量来判断用不用projection,这样就用了projection导致最终呈现出来的查询时间变长了。所以不用projection这种方案。
2.2 个性化sql优化
相比于18集群,173集群已经重建了分片字段,之前使用dt,现在用skuid,查询并发读和效率已经提高了很多。
针对不同请求接口具体分析请求超时原因,采用不同的优化方案:
- 商品榜单:更改请求sql,改用本地聚合;
- 品牌榜单:使用字典关联维表;
- 店铺榜单:关联维表使用字典dictget函数;
- 行业趋势:
1)行业概况商品榜单
重建分区键之后,使用settings distributed_group_by_no_merge = 1直接进行本地聚合,不再在分布式表中聚合所有数据。
优化前7.3s
优化后1.2s
1 | select |
2)行业概况品牌榜单
发现uniqMergeState好像不仅没有提升效率,反而还降低了效率,主要还是使用字典对效率提升很高。
优化前4.5s
1 | select |
优化后1.6s
1 | select |
3)行业概况店铺榜单
这是一个按成交金额排序的榜单,优化点主要是先只算成交金额一个指标的榜单,把前十店铺给先扒出来了,然后再算这是个店铺的所有指标,这样对效率的提升很大。
优化前3.4s
1 | select |
优化后1.4s
1 | select |
4)行业趋势
把从同一张表里出的指标放到同一张表中去,就是纯sql结构优化。
优化前2.5s
1 | select |
优化后1.9s
1 | select |