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 算法,以达到最佳的性能和内存利用效果。
相关推荐
关中雪5 分钟前
【应届应知应会】SQL常用知识点50道
数据库·mysql·nosql·秋招·校招·春招
zxrhhm16 分钟前
MySQL中使用PROFILING来查看SQL执行流程
数据库·mysql
醇氧16 分钟前
【postgresql】表操作
数据库·sql·postgresql
PGCCC17 分钟前
使用预加载库优化 PostgreSQL 函数#postgresql认证
数据库·postgresql
baozongwi1 小时前
CTF常用sql注入(一)联合注入和宽字节
数据库·sql·web安全
freesharer1 小时前
Zabbix 配置WEB监控
前端·数据库·zabbix
尾巴尖上的阳光1 小时前
ETCD概述--使用/特性/架构/原理
数据库·架构·etcd
关兮月1 小时前
MySQL存储与优化 一、MySQL架构原理
数据库·mysql
我想我不够好。1 小时前
SQL-DQL
数据库·sql
风中的默默1 小时前
《深入浅出MySQL:数据库开发、优化与管理维护(第3版)》
数据库·mysql·数据库开发