clickhouse join内存溢出

clickhouse join 内存溢出

前言

在一个离线工作流中任务报错

java 复制代码
Code: 241. DB::Exception: Received from XXXXXX:9000. DB::Exception: Memory limit (for query) exceeded: would use 20.49 GiB (attempt to allocate chunk of 4413264 bytes), maximum: 20.49 GiB: (avg_value_size_hint = 43, avg_chars_size = 42, limit = 8192): (while reading column level_system_name): (while reading from part /data/clickhouse/clickhouse-server/store/eb1/eb151646-ab48-48e6-866b-f5bf913470a1/all_305_310_1/ from mark 432 with max_rows_to_read = 8192): While executing MergeTreeThread. (MEMORY_LIMIT_EXCEEDED)

接下来是排查步骤和处理方法

排查步骤

查看sql

sql 复制代码
SET max_memory_usage = 22000000000;
insert into  A(
    column........
) Select
	column......
From B 
    Left Join C i
      On C.id = B.id;

统计数据量

B 表大概9000w

C 表大概5000w

统计大小

sql 复制代码
SELECT
    table,
    formatReadableSize(sum(data_compressed_bytes)) AS compressed_size,
    formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed_size,
    formatReadableSize(sum(bytes_on_disk)) AS size
FROM system.parts
WHERE table = 'A'
GROUP BY table;

最开始只统计了 bytes_on_disk 发现两张表都不超过2G,就很纳闷内存都已经给到22G 了还是不够,后来才发现是压缩之后的,压缩前A 8G B 11G

优化索引

经过检查 关联条件都在索引,没办法优化了

优化字段

经过检查select 的字段下游都有用到,也无法优化

增加内存

想修改max_memory_usage 参数,但是无限制的加内存也不是解决办法

最终优化

修改了 join的算法

sql 复制代码
insert into  A(
    column........
) Select
	column......
From B 
    Left Join C i
      On C.id = B.id
      Settings join_algorithm='partial_merge';

下面是ChatGPT给出的join 算法解释

txt 复制代码
在 ClickHouse 中,JoinAlgorithm 参数指定了执行 JOIN 操作时使用的算法。这些算法可以通过设置来优化查询的性能和内存利用情况。以下是各个 JoinAlgorithm 的含义和作用:

1. **prefer_partial_merge**
   - 这个选项表示 ClickHouse 首选使用部分合并(partial_merge)算法来执行 JOIN 操作。
   - 部分合并算法会尽量在不需要将整个数据集加载到内存中的情况下执行 JOIN,因此在处理大数据量时可以减少内存的使用。
   - 如果部分合并算法不适用或无法使用,ClickHouse 会尝试使用其他适当的 JOIN 算法。

2. **hash**
   - 使用哈希 JOIN 算法来执行 JOIN 操作。
   - 哈希 JOIN 是一种内存密集型算法,适合处理较小的数据集或者对性能要求较高的场景,因为它通常比其他 JOIN 算法更快速。
   - 这种算法会将数据加载到内存中,使用哈希表来快速查找匹配的行。

3. **partial_merge**
   - 使用部分合并 JOIN 算法来执行 JOIN 操作。
   - 部分合并算法尝试在不需要加载整个数据集到内存中的情况下执行 JOIN,这在处理大数据量时可以节省内存和提高性能。
   - 它适合处理无序数据或者在其中一个表的数据较大时,可以减少内存压力。

4. **auto**
   - ClickHouse 自动选择适当的 JOIN 算法来执行操作。
   - 这是默认的选项,ClickHouse 会根据查询的具体情况和表的大小自动选择合适的 JOIN 算法,以达到最佳的性能和内存利用效果。
相关推荐
r i c k11 分钟前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦25 分钟前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL1 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·1 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德1 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫2 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i2 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.2 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn2 小时前
【Redis】渐进式遍历
数据库·redis·缓存
橙露3 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot