首页
/ ClickHouse 24.4版本中ORDER BY DESC查询性能下降问题分析

ClickHouse 24.4版本中ORDER BY DESC查询性能下降问题分析

2025-05-02 22:10:52作者:柏廷章Berta

在ClickHouse 24.4版本发布后,用户反馈在执行带有ORDER BY DESC和LIMIT的查询时出现了显著的性能下降。本文将从技术角度深入分析这个问题的成因、影响范围以及临时解决方案。

问题现象

用户在使用ClickHouse 24.4版本执行如下查询时发现了性能问题:

SELECT * FROM hits ORDER BY CounterID DESC LIMIT 1000 SETTINGS max_threads = 32

与24.3版本相比,24.4版本中该查询表现出以下异常特征:

  1. 执行时间从4.196秒增加到26.918秒
  2. 处理的数据量从50.31千行增加到292.54千行
  3. 内存使用从215.77MB激增至964.63MB

根本原因分析

通过深入调查,发现问题源于24.4版本中引入的多线程读取优化。具体表现为:

  1. 多线程读取机制变更:24.4版本开始使用多个线程并行读取单个数据部分(part),旨在提高大范围数据扫描的性能
  2. 反向排序的特殊性:在ORDER BY DESC场景下,多个线程会重复读取相同的granule(数据颗粒)
  3. 资源浪费:测试显示最多有48个读取线程同时工作,导致大量冗余I/O操作

技术细节

在正常执行流程中:

  • 每个线程尝试读取约1000行数据
  • 由于是反向排序,多个线程会从不同偏移量开始读取
  • 导致相同的数据granule被多个线程重复加载

通过查询计划分析发现:

Reading 21 ranges in reverse order from part 20130703-0_9_9_4
Reading 52 ranges in reverse order from part 20130703-0_9_9_4 
Reading 52 ranges in reverse order from part 20130703-0_9_9_4
...

相同part被多次读取,且读取范围有大量重叠。

临时解决方案

用户发现通过修改查询结构可以规避此问题:

SELECT * FROM (
    SELECT * FROM hits 
    ORDER BY CounterID DESC 
    LIMIT 1000000000000000000
    SETTINGS max_threads = 32
) LIMIT 1000

这种写法使得:

  1. 内层查询完整扫描数据并排序
  2. 外层仅做LIMIT过滤
  3. 执行计划变为顺序读取,避免了多线程重复读取

测试显示该方案使:

  • 执行时间从7.404秒降至1.4秒
  • 内存使用从1.14GB降至460MB
  • 读取线程数从48降至17

版本影响范围

问题首次出现在24.4版本,与以下变更相关:

  1. 多线程读取优化引入
  2. 反向排序场景的特殊处理缺失
  3. 资源分配策略调整

24.3及之前版本不受此问题影响,保持原有的高效执行方式。

最佳实践建议

对于受影响的用户,建议:

  1. 在升级到24.4+版本时,评估ORDER BY DESC查询性能
  2. 对于关键查询,考虑使用上述临时解决方案
  3. 监控系统资源使用情况,特别是I/O和内存
  4. 关注后续版本中此问题的官方修复

该问题凸显了数据库优化中平衡并行度和资源使用的重要性,特别是在特殊查询场景下的边际效应。ClickHouse团队预计将在后续版本中针对此特定场景进行优化调整。

登录后查看全文
热门项目推荐
相关项目推荐