Hologres 查询优化过程实战
1 分析查询过程
这里涉及到两部分东西 ,一个是表的存储 也就是建表时侯的各种参数,另一个是表的查询,我们分开讨论,分开分析。
这种东西如果不知道从哪里入手,那么从使用往回推是肯定没问题的,我们默认啊的字段是按照三范式来做的,也就是说 不考虑字段的冗余存储,这总情况下直接先从使用处 往回倒推肯定没毛病好吧。
1 使用分析命令 分析查询sql
说的简单点 分析执行命令 使用 EXPLAIN analyze 分析查询语句,我们可以看到每个语句分别在做什么,分别触发了什么索引。
索引这个东西,在不关注的时候没甚么用,单节点部署的hologres也没甚么用,但是在shard数,数据量,表的维度 ,等等某些东西多的时候,他的作用就会不知不觉的显现出来,例如 十几万的查询,如果索引设置的不合理,可能需要查询 1000多ms,如果合理的话 可能100ms就足够了,这是1000%的查询性能提升啊,如果一个app的页面又50个接口,每个接口查5个表,这个提升可就大了,所以索引如何设置 ,每种索引有什么作用 可以参考我的 另一篇帖子 。:hologres 建表/索引/查询优化,或者背诵下图:
那么好 我们实战来看一下
根据分析结果 我们看下
说了什么呢,说我们的 distribution_key ,没有被命中,这个索引的设置记住几个词,尽量分散,尽量全部命中,尽量别超过2个,一定是主键的子集。所以我们按照他的优化结果来
把distribution_key 也就是 存储的分布键,设置为他说的两个字段,之后再分析
足够明显吧
这里附上表的索引设置
2 查询优化命令
这里是说 hologres 在不停更新,他每个版本都有一些新的能力,如果升到3.1,会有一些能力。
例如 我们可以配置以下参数,来减少查询时候的 数据shuffle。
常用的SQL性能优化参数:
–关闭数据重分布
– set optimizer_enable_motion_redistribute = true;
–关闭cache
set hg_experimental_enable_result_cache = off;
set hg_experimental_enable_query_use_block_cache = off;
–开启hint语法支持
SET pg_hint_plan_enable_hint=on;
–打开详细执行计划
– set hg_experimental_show_execution_statistics_in_explain = on;
–常规执行计划
Explain Analyze
–巨详细执行计划(JSON)
– explain (format pb)
指定query关闭数据重分布,降低shuffle消耗方法:
SET pg_hint_plan_enable_hint=on;
WITH dim_sale_org AS (
SELECT/*+HINT set(optimizer_enable_motion_redistribute off) */
3 数据计算组
这里是什么意思呢,数据表在存储的时候是要设置数据计算组的,hologres 1个workder,16个cu,1个workder最少1个shard(数据分片数)如果没有shard,那这个workder就无法被配工作。
但是如果你的表数据量很小,shard还比较多的话,他就会被分散到很多的shard中,反而降低了效率,所以可以设计几个数据计算组,分别有不同的shard数,小表设置的计算组shard数量少,大表设置的计算组的shard数量多。一方面可以做资源隔离,另一方面提高计算效率
4 hologres 大量点查 也就是 flink lookup join holo表
hologres 一般都是与flink一起使用,所以hologres表做 flink的 lookup join 维表也是常见场景,有人应该发现了,如果用hologres维表 ,有时候任务会阻塞死,这种情况是因为维表 join的键不是表的主键,这种情况会发生阻塞,实际上还是大量点查导致的。
5 定期巡检分布键
1、查hologres.hg_table_info 这张表,抠出来里面的distribution_key,然后常见字段匹配(ymd等等)+人工确认结合
2、计算组10里面加新的巡检任务,去统计每张表的数据分布是否存在数据倾斜,select hg_shard_id, count(1) from bi_car.ads_wide_ord_pipeline_ssu_price_rt_yu7sale group by hg_shard_id; 然后比一下偏差情况
可以配置单worker cpu打满告警和倾斜告警
6 查看holo实时写入情况
select
query,
command_tag, count(1), avg(cpu_time_ms)::bigint, sum(cpu_time_ms)::bigint
from hologres.hg_query_log
where 1 = 1
and query_start >= ‘2025-05-21 13:20:00+08’
and query_start <= ‘2025-05-25 02:42:00+08’
group by 1,2
order by 2 desc
limit 100;