首页 > 解决方案 > 如何提高clickhouse的查询速度

问题描述

在clickhouse中,我想做一个查询操作。查询中包含group by QJTD1,但是QJTD1是通过查询字典得到的。声明如下:

`SELECT
IF(
    sale_mode = 'owner',
    dictGetString(
        'dict.dict_sku',
        'dept_id_1',
        toUInt64OrZero(sku_id)
    ),
    dictGetString(
        'dict.dict_shop',
        'dept_id_1',
        toUInt64OrZero(shop_id)
    )
) AS QJTD1,
brand_cd,
coalesce(
    uniq(sd_deal_ord_user_num),
    0
) AS sd_deal_ord_user_num,
0 AS item_uv,
dt
FROM app.test_all
WHERE dt >= '2020-11-01'
AND dt <= '2020-11-30'
and IF(
    sale_mode = 'owner',
    dictGetString(
        'dict.dict_sku',
        'bu_id',
        toUInt64OrZero(sku_id)
    ),
    dictGetString(
        'dict.dict_shop',
        'bu_id',
        toUInt64OrZero(shop_id)
    )
)= '1727' GROUP BY
QJTD1,
brand_cd,
dt
ORDER BY item_pv desc limit 0,
100`

,QJTD1数据倾斜严重,导致查询速度慢。我曾尝试优化索引以提高查询速度。索引如下:sku_id,shop_id....但是没有效果。如何提高查询效率?

标签: clickhouse

解决方案


CH 总是计算 IF (then & else) 的两个分支。

您可以使用两阶段组

select IF( sale_mode ='owner', ... as QJTD1
from (  
  select owner, sku_id, dept_id_1, ....
  ...
  group by owner, sku_id, dept_id_1
  )
group by QJTD1

或者定义字典<injective>true

https://clickhouse.tech/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure/

显示 id -> 属性图像是否单射的标志。
如果为 true,ClickHouse 可以自动放置在 GROUP BY 之后
用注入子句对字典的请求。通常它
大大减少了此类请求的数量。

默认值:假。

如果它们是内射的。

然后我会测试Union all只计算一次 IF 分支。


推荐阅读