system.query_log 识别反复出现的慢查询模式,选择一次具有代表性的执行,并查看其资源使用情况。随后,您将使用 EXPLAIN 检查查询计划,在修改查询或 schema 前对性能瓶颈提出假设。
开始之前
nyc_taxi.trips_small_inferred 表。若要按文中所示运行这些示例,如尚未创建并加载该表,请执行以下操作:
设置示例数据集
设置示例数据集
源 Parquet 文件约为 5.8 GB。加载该文件可能需要几分钟,具体取决于您的网络状况和可用资源。
SYSTEM FLUSH LOGS,请等待查询日志自动刷写后再重试首次查找。诊断自己的工作负载时,请确保 system.query_log 包含您要检查的时间范围内已完成的查询记录。
工作原理
system.query_log 表中。每条记录可包含查询耗时、读取行数、CPU 和内存使用情况,以及文件系统缓存活动。
这些指标可帮助您识别慢查询模式,并了解其资源使用情况。选择一次具有代表性的执行后,您可以检查其查询计划,分析查询可能在哪些环节耗时。
在集群中,查询日志数据保留在各个节点本地。本指南中的示例使用 clusterAllReplicas 查询所有副本,并使用 merge 纳入当前的 system.query_log 表,以及系统表 schema 变更后保留的所有版本化 query_log_N 表。
每个查询日志示例都提供集群部署和单节点部署的选项卡。ClickHouse Cloud 提供了集群示例中使用的 default 集群。在自管理部署中,请将 default 替换为 system.clusters 中列出的集群。
这些示例设置了
skip_unavailable_shards,以确保暂时不可用的副本不会导致诊断查询失败。这在扩缩容期间尤其有用。被跳过副本中的记录不会包含在结果中,因此结果可能不完整。诊断慢查询
识别候选查询
首先按 使用
normalized_query_hash 对已完成的初始查询进行分组,从而将反复出现的查询模式与个别的慢执行区分开来。下面的查询会按中位耗时对各类模式排序,并为每种模式给出一个示例查询:- 集群
- 单节点
executions 可以区分反复出现的 workload 与偶发的 queries。相比单次运行较慢的查询,中位耗时较高、执行频繁或 resource 消耗较大的 pattern 更值得优先调查。为快速摸清情况,下面的查询会针对 NYC Taxi 数据集,列出最多五个不同查询模式各自最慢的一次已完成执行,并排除数据集加载语句以及同一模式的重复执行。在下一步中,你将把查询历史缩小到与上面所选 normalized_query_hash 相对应的执行记录。- 集群
- 单节点
query_duration_ms 字段表示查询耗时,单位为毫秒。在上述结果中,耗时最长的查询用了 2,967 毫秒。你也可以根据资源使用情况 (而非查询耗时) 来定位候选查询:查找资源消耗高的查询
查找资源消耗高的查询
此查询按内存使用量对最近的查询进行排序,并显示其 CPU 使用情况。结果因工作负载和部署方式而异:
- 集群
- 单节点
选择一次有代表性的查询执行
单次运行缓慢可能只是异常值,由临时查询或短暂的系统负载所致。在检查查询计划前,请查看多次具有相同 示例查询日志结果显示,每个候选查询读取了约 3.2904 亿行。为便于参考,请确认示例表中的行数:该表包含 3.2904 亿行,与每个候选项中
normalized_query_hash 的已完成运行;仅字面量值不同的查询具有相同的哈希值。选择一次能代表该模式典型耗时和资源使用情况的运行。将 selected_hash 的值替换为要调查模式的 normalized_query_hash:- 集群
- 单节点
- 查找
read_rows和read_bytes相近的运行记录。 - 比较这些运行记录的
query_duration_ms和memory_usage。 - 选择
query_duration_ms最接近中位数的query_id。
历史查询日志结果会随缓存状态和系统负载而变化,因此应使用它们来选择要调查的查询,而不应用于比较优化前后的变化。如果查询日志中没有足够的已完成运行记录,请在相似条件下运行该查询几次。下一篇指南 隔离查询瓶颈 介绍了如何收集受控测量数据,以便比较变更。
read_rows 报告的行数大致相同。这表明查询扫描了表中的大部分或全部数据,但无法解释为何读取这些行,也无法判断这样的读取量是否适合该查询。接下来检查查询计划,了解 ClickHouse 如何选择和处理数据。查看执行计划
选择一次具有代表性的运行后,使用 输出包含以下操作。parts 和粒度等详细信息的数量取决于数据的存储方式:自下而上,该执行计划与查询的对应关系如下:
EXPLAIN 查看 ClickHouse 如何规划查询,而无需实际执行查询。输出会显示 ClickHouse 预计执行的操作以及数据如何在这些操作之间流动,为理解查询日志中的指标提供更多背景信息。有关可用输出格式的详细介绍,请参阅使用 analyzer 理解查询执行。在此示例中,EXPLAIN 会显示 ClickHouse 计划如何读取和过滤数据,以及能否跳过其中的部分数据。输出是一个操作树,展示 ClickHouse 预计如何读取、过滤和处理数据。子操作显示在其父操作下方。请从最深层的读取操作开始,再沿计划向上查看 ClickHouse 如何将数据转换为最终结果。在本示例中,请查看查询日志结果中的计算速度查询:ReadFromMergeTree从nyc_taxi.trips_small_inferred读取数据。未显示Indexes部分,且read_rows与表的行数一致,表明 ClickHouse 会读取整张表。Filter显示了speed_mph > 30的展开表达式。对于读取的每一行,ClickHouse 都会计算行程耗时和速度,然后仅保留速度超过每小时 30 英里的行。Aggregating根据过滤后的trip_distance值计算分位数。
speed_mph,以及计算分位数。