为啥将 OFFSET 添加到 clickhouse 查询会增加执行时间?

Posted

技术标签:

【中文标题】为啥将 OFFSET 添加到 clickhouse 查询会增加执行时间?【英文标题】:Why adding OFFSET to the clickhouse query increase execution time?为什么将 OFFSET 添加到 clickhouse 查询会增加执行时间? 【发布时间】:2020-03-12 14:09:39 【问题描述】:

我有一个包含大约 900 万条记录的表。当我尝试选择具有大偏移量的记录(用于分页)时,它会将执行时间增加到极值。甚至导致超出内存限制而失败。

这里有两个不同偏移值的查询日志。

SELECT * WHERE set_date >= '2019-10-11 11:05:00' AND set_date OFFSET 30

已用时间:0.729 秒。 处理了 992 万行,3.06 GB(1361 万行/秒,4.19 GB/秒。)
MemoryTracker:内存使用峰值(用于查询):181.65 MiB。

SELECT * WHERE set_date >= '2019-10-11 11:05:00' AND set_date OFFSET 3000000

已用时间:6.301 秒。 处理了 992 万行,3.06 GB(157 万行/秒,485.35 MB/秒。) MemoryTracker:内存使用峰值(用于查询):5.89 GiB。

【问题讨论】:

您可以尝试使用带 Id 的 Between 命令吗? SELECT * (missing the from table here) WHERE set_date BETWEEN ''2019-10-11 11:05:00' AND '2019-10-19 18:09:59' and id between 1 and 3000000 ORDER BY id ASC 您能提供表架构吗?我怀疑使用了像 ORDER BY (set_date, id) 这样的 PK,如果正确,请尝试 select .. order by set_date, id limit 1 offset 3000000 你为什么从任何表中选择 *?使用您关心的列名来节省完成查询所需的资源。使用开始日期和结束日期之间经过的时间是多少(如 Pimenta 建议的那样)?但是你需要一个可能不可用的日期的索引。 【参考方案1】:

包括 CH 在内的所有数据库都以相同的方式实现OFFSET。他们只是读取所有行并在结果集中跳过OFFSET。没有优化直接上升到 OFFSET 3000000。

https://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/

尝试禁用 optimize_read_in_order 以修复内存使用情况

SELECT * 
WHERE set_date >= '2019-10-11 11:05:00' 
AND set_date <= '2019-10-19 18:09:59' 
ORDER BY id ASC LIMIT 1 OFFSET 3000000
setting optimize_read_in_order=0

【讨论】:

以上是关于为啥将 OFFSET 添加到 clickhouse 查询会增加执行时间?的主要内容,如果未能解决你的问题,请参考以下文章

为啥clickhouse写批记录慢?

Clickhouse 词典:为啥 CREATE DICTIONARY 需要数据库?

为啥修改表格列clickhouse时出现错误

为啥我不能将 clickhouse json 函数应用于“FORMAT JSON”查询结果?

在 clickhouse 中创建表时如何将自定义默认值添加到 Nullable 类型?

为啥我们不能在 clickhouse 的另一个视图之上制作物化视图?