Clickhouse limit by函数

关注微信公共号:小程在线

关注CSDN博客:程志伟的博客

 ClickHouse server version 21.6.6

创建表

dblab-VirtualBox :) CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory;

CREATE TABLE limit_by
(
    `id` Int,
    `val` Int
)
ENGINE = Memory

Query id: 892b335b-f25f-4aef-ba60-5281dd752c1b

Ok.

0 rows in set. Elapsed: 0.006 sec. 

dblab-VirtualBox :) INSERT INTO limit_by VALUES (1, 10), (1, 11), (2, 12), (3, 20), (3, 21);

INSERT INTO limit_by VALUES

Query id: 85429b01-5d58-4104-a550-bc477e158465

Ok.

5 rows in set. Elapsed: 0.011 sec. 

dblab-VirtualBox :) select * from limit_by;

SELECT *
FROM limit_by

Query id: ec740af6-c451-4985-81b5-243106333a5a

┌─id─┬─val─┐
│  1 │  10 │
│  1 │  11 │
│  2 │  12 │
│  3 │  20 │
│  3 │  21 │
└────┴─────┘

5 rows in set. Elapsed: 0.004 sec.

按照分组每个id取2个值

dblab-VirtualBox :) SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id

SELECT *
FROM limit_by
ORDER BY
    id ASC,
    val ASC
LIMIT 2 BY id

Query id: 5d5c937e-fc56-4393-a36e-03a17c1beb25

┌─id─┬─val─┐
│  1 │  10 │
│  1 │  11 │
│  2 │  12 │
│  3 │  20 │
│  3 │  21 │
└────┴─────┘

5 rows in set. Elapsed: 0.003 sec. 

 

 

从第1位之后取值,取2个

dblab-VirtualBox :) SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id

SELECT *
FROM limit_by
ORDER BY
    id ASC,
    val ASC
LIMIT 1, 2 BY id

Query id: ee616bee-c7ca-4e0b-bca5-44dd1f145374

┌─id─┬─val─┐
│  1 │  11 │
│  3 │  21 │
└────┴─────┘

2 rows in set. Elapsed: 0.004 sec. 

 

### ClickHouse MEMORY_LIMIT_EXCEEDED 报错的原因及解决方案 #### 原因分析 ClickHouse 中 `MEMORY_LIMIT_EXCEEDED` 错误通常发生在查询过程中使用的内存超过了设定的最大限制。默认情况下,ClickHouse 对单个查询的内存使用上限设置为 10 GiB[^1]。如果某个查询尝试分配超过此限制的内存,则会触发该错误。 这种问题可能由以下几个因素引起: 1. **大数据集处理**:当查询涉及大量数据(如扫描近200M行的数据),可能会消耗较多内存资源。 2. **复杂计算操作**:某些聚合函数(如 `uniqExact`)或复杂的 JOIN 和 GROUP BY 操作可能导致更高的内存需求。 3. **不合理的配置参数**:例如未调整 `max_memory_usage` 或其他相关参数,使得系统无法适应高负载场景下的内存需求。 --- #### 解决方案 ##### 方法一:增加最大允许内存限制 可以通过修改 ClickHouse 配置文件中的 `max_memory_usage` 参数来提升单次查询可使用的最大内存量。具体做法是在配置文件中添加或更改以下字段: ```xml <profiles> <default> <!-- 设置新的内存限制 --> <max_memory_usage>20000000000</max_memory_usage> <!-- 单位字节, 此处设为20GB --> </default> </profiles> ``` 或者通过 SQL 动态调整当前 session 的内存限制: ```sql SET max_memory_usage = '20Gi'; ``` 这种方法适用于临时需要更高内存支持的情况,但需谨慎评估硬件条件以防止 OOM (Out of Memory)。 ##### 方法二:优化查询逻辑 重新设计查询语句可以显著降低其对内存的需求。以下是几种常见的优化手段: - 替换耗内存较高的聚合函数;比如用更高效的近似算法代替精确去重(`uniqExact`)。 - 减少中间结果大小——利用过滤器提前排除不必要的记录。 对于大规模数据集合上的运算尤其重要的是考虑分步执行策略而不是一次性加载整个数据集到内存里完成所有工作流。 ##### 方法三:启用分布式模式或多节点部署 如果单一服务器难以满足高性能需求,那么构建集群环境将是另一个可行的选择。借助副本机制(replication),不仅可以提高可用性和容灾能力,还能分散读写压力从而缓解局部资源紧张状况[^2]。 另外,在多台机器上平行运行相同任务也可以有效分割原始问题规模进而减少个体负担。 ##### 方法四:合理应用采样技术 针对那些不需要绝对精准统计的应用场合来说,采用样本估算往往能带来事半功倍的效果。MergeTree引擎家族成员本身就具备良好的原生支持特性,只需定义好相应的抽样表达式即可开启这项功能[^3]。 最后值得注意的一点是网络层面超时控制同样不容忽视,适当延长连接等待时限有助于避免因为短暂延迟而导致失败中断现象发生[^4]。 --- ### 总结 综上所述,面对 ClickHouse 查询过程中可能出现的 `MEMORY_LIMIT_EXCEEDED` 异常情况,可以从多个角度出发寻找对应措施加以应对。无论是直接扩大物理容量边界还是深入挖掘业务特点寻求替代路径都值得探索实践一番。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值