你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文档介绍作为 Kusto 查询响应的一部分返回的资源消耗信息。
执行查询时,服务不仅返回查询结果,还会返回有关查询执行期间使用的资源的详细信息。
了解查询资源消耗数据有助于优化查询性能、识别瓶颈以及规划适当的资源分配。 通过随着时间的推移监视这些指标,可以做出有关查询设计、群集配置和数据组织的明智决策,以确保 Kusto 查询的最佳性能和成本效益。
资源消耗数据作为查询响应的一部分在对象中 QueryResourceConsumption
返回,通常采用 JSON 格式。 可以在 监视工具 中或通过 编程访问查找对象。
QueryResourceConsumption 对象的结构
该 QueryResourceConsumption
对象通常包含以下主要部分:
-
QueryHash
:查询结构的唯一标识符。 此哈希表示没有其文本值的查询,即使特定文本值不同,也允许识别类似的查询模式。 例如,类似Events | where Timestamp > datetime(2023-01-01)
查询并且Events | where Timestamp > datetime(2023-02-01)
具有相同的 QueryHash,因为它们共享相同的结构,只是与文本日期/时间值不同。 -
ExecutionTime
:总执行时间(以秒为单位) -
resource_usage
:已用资源的详细细分 -
input_dataset_statistics
:有关已处理 的数据输入的 统计信息 -
dataset_statistics
:有关生成的数据集的统计信息 -
cross_cluster_resource_usage
:有关在相关群集中使用的资源的信息
资源使用情况详细信息
资源使用情况部分提供有关查询执行期间使用的资源的详细信息。 它包括了以下几节:
-
resource_usage.cache.shards
:有关缓存使用情况的信息 -
resource_usage.cpu
:有关 CPU 使用情况的信息 -
resource_usage.memory
:有关内存使用情况的信息 -
resource_usage.network
:有关网络使用情况的信息 -
input_dataset_statistics
:有关输入数据集的信息
缓存使用情况
本 resource_usage.cache.shards
部分提供有关查询如何使用缓存的信息:
物体 | 资产 | DESCRIPTION |
---|---|---|
hot |
从热缓存提供的数据 | |
hitbytes |
从热缓存成功检索的数据量(以字节为单位) | |
missbytes |
热缓存中未找到的数据量(以字节为单位) | |
retrievebytes |
从存储中检索的数据量,以满足未命中数(以字节为单位) | |
cold |
从冷缓存提供的数据 | |
hitbytes |
从冷缓存成功检索的数据量(以字节为单位) | |
missbytes |
冷缓存中找不到以字节为单位的数据量(以字节为单位) | |
retrievebytes |
从存储中检索的数据量,以满足未命中数(以字节为单位) | |
bypassbytes |
绕过缓存的数据量(以字节为单位) | |
results_cache_origin |
有关缓存和重用其结果的原始查询的信息 | |
client_request_id |
填充缓存的原始请求的唯一标识符 | |
started_on |
执行填充缓存的原始查询时的时间戳 | |
partial_query_results |
每个分片级别的缓存的统计信息(如果已启用) | |
hits |
缓存中找到的分片级查询结果数 | |
misses |
缓存中缺少的分片级查询结果数 |
CPU 使用率
本 resource_usage.cpu
部分提供有关 CPU 消耗的信息:
物体 | 资产 | DESCRIPTION |
---|---|---|
user |
用户模式 CPU 时间 | |
kernel |
内核模式 CPU 时间 | |
total cpu |
占用的总 CPU 时间 | |
breakdown |
CPU 使用率进一步细分 | |
query execution |
查询执行的 CPU 时间 | |
query planning |
查询规划的 CPU 时间 |
内存使用情况
本 resource_usage.memory
部分提供有关内存消耗的信息:
物体 | 资产 | DESCRIPTION |
---|---|---|
peak_per_node |
每个节点的内存使用率峰值(以字节为单位) |
网络用途
本 resource_usage.network
部分提供有关网络使用情况的信息:
物体 | 资产 | DESCRIPTION |
---|---|---|
inter_cluster_total_bytes |
群集中传输的总字节数 | |
cross_cluster_total_bytes |
跨群集传输的总字节数 |
输入数据集统计信息
本 input_dataset_statistics
部分提供有关已处理的源数据的详细信息:
物体 | 资产 | DESCRIPTION |
---|---|---|
extents |
有关数据盘区的信息 | |
total |
查询引用的所有表中的盘区总数 | |
scanned |
扫描的盘区数(由查询节点检查) | |
scanned_min_datetime |
扫描数据的最低日期/时间 | |
scanned_max_datetime |
扫描数据的最大日期/时间 | |
rows |
有关数据行的信息 | |
total |
查询引用的所有表中的行总数 | |
scanned |
扫描的行数(由查询节点检查) | |
rowstores |
有关行存储数据的信息 | |
scanned_rows |
从行存储扫描的行数 | |
scanned_values_size |
从行存储扫描的值的大小 | |
shards |
有关分片查询的信息 | |
total |
查询引用的所有表中的分片总数 | |
scanned |
扫描的分片数(由查询节点检查) | |
external_data |
有关外部数据的信息(如果适用) | |
downloaded_items |
从外部数据源下载的项目数 | |
downloaded_bytes |
从外部数据源下载的字节数 | |
iterated_artifacts |
从外部数据源迭代的项目数 |
与监视工具集成
可以随着时间的推移收集和分析 QueryResourceConsumption 数据,以确定查询性能中的趋势和异常。 可通过以下方法获取此数据:
- 查询执行结果
-
.show queries
命令输出 - 导出到监视解决方案的诊断日志
监视此数据有助于识别查询优化机会,并跟踪对数据模型或查询模式的更改的影响。
查询执行结果
可以直接从查询执行结果访问 QueryResourceConsumption 数据的原始 JSON 文件。 信息显示在查询编辑器下方的结果网格中。
在查询窗格中运行查询。
浏览到查询结果的 “统计信息 ”选项卡。
查看 原始 JSAN 预览 部分,然后选择 “查看完整 JSON ”选项以滚动浏览原始 JSON。
程序化访问
在客户端应用程序中,可以通过编程方式访问 QueryResourceConsumption 信息:
// Example of accessing QueryResourceConsumption in C#
var dataSet = kustoClient.ExecuteQuery(query);
var resourceConsumption = GetQueryResourceConsumption(dataSet.Tables[2], false);
Console.WriteLine($"Execution time: {resourceConsumption.ExecutionTime}");
Console.WriteLine($"Memory peak: {resourceConsumption.ResourceUsage.Memory.PeakPerNode}");
有关详细信息,请参阅 创建应用以运行管理命令。
例子
热缓存中的数据:此示例显示完全从热缓存(:517324:hitbytes
:0)提供且执行时间最少(missbytes
0.0045931 秒)的查询。 在热缓存中找到所有数据,导致查询执行速度非常快。
{
"QueryHash": "add172cd28dde0eb",
"ExecutionTime": 0.0045931,
"resource_usage": {
"cache": {
"shards": {
"hot": {
"hitbytes": 517324,
"missbytes": 0,
"retrievebytes": 0
},
"cold": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"bypassbytes": 0
}
},
"cpu": {
"user": "00:00:00",
"kernel": "00:00:00",
"total cpu": "00:00:00",
"breakdown": {
"query execution": "00:00:00",
"query planning": "00:00:00"
}
},
"memory": {
"peak_per_node": 1580848
},
"network": {
"inter_cluster_total_bytes": 27384,
"cross_cluster_total_bytes": 0
}
},
"input_dataset_statistics": {
"extents": {
"total": 1,
"scanned": 1,
"scanned_min_datetime": "2016-03-17T08:24:02.6259906Z",
"scanned_max_datetime": "2016-03-17T08:24:02.6259906Z"
},
"rows": {
"total": 59066,
"scanned": 59066
},
"rowstores": {
"scanned_rows": 0,
"scanned_values_size": 0
},
"shards": {
"queries_generic": 1,
"queries_specialized": 0
}
},
"dataset_statistics": [
{
"table_row_count": 10,
"table_size": 11473
}
],
"cross_cluster_resource_usage": {}
}
外部表中的数据:此示例显示了处理外部数据的查询。 请注意高执行时间(159.88 秒)和大量 CPU 利用率(超过 1 小时的总 CPU 时间)。 外部数据部分显示已下载 6,709 个项目,总计约 87.7 GB。 对于需要从外部源提取大量数据的查询,这比查询 Kusto 内部存储中的数据要慢得多。
{
"QueryHash": "529656ef4099485b",
"ExecutionTime": 159.8833962,
"resource_usage": {
"cache": {
"shards": {
"hot": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"cold": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"bypassbytes": 0
}
},
"cpu": {
"user": "01:01:13.5312500",
"kernel": "00:00:44.9687500",
"total cpu": "01:01:58.5000000",
"breakdown": {
"query execution": "01:01:58.5000000",
"query planning": "00:00:00"
}
},
"memory": {
"peak_per_node": 26834528
},
"network": {
"inter_cluster_total_bytes": 6745,
"cross_cluster_total_bytes": 0
}
},
"input_dataset_statistics": {
"extents": {
"total": 0,
"scanned": 0,
"scanned_min_datetime": "0001-01-01T00:00:00.0000000Z",
"scanned_max_datetime": "0001-01-01T00:00:00.0000000Z"
},
"rows": {
"total": 0,
"scanned": 0
},
"rowstores": {
"scanned_rows": 0,
"scanned_values_size": 0
},
"shards": {
"queries_generic": 0,
"queries_specialized": 0
},
"external_data": {
"downloaded_items": 6709,
"downloaded_bytes": 87786879356,
"iterated_artifacts": 6709
}
},
"dataset_statistics": [
{
"table_row_count": 2,
"table_size": 44
}
],
"cross_cluster_resource_usage": {}
}
来自冷缓存的数据:此示例显示了从冷缓存检索数据的查询(cold.hitbytes
:127209)。 请注意,在总共 1,250 个盘区中,只扫描了 1 个,在总共 50,000 行中,仅扫描了 40 个。 这建议使用适当筛选的高效查询。 冷缓存访问通常比热缓存慢,但比直接从存储检索数据更快。
{
"QueryHash": "480873c9b515cea8",
"ExecutionTime": 1.4233768,
"resource_usage": {
"cache": {
"shards": {
"hot": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"cold": {
"hitbytes": 127209,
"missbytes": 0,
"retrievebytes": 0
},
"bypassbytes": 0
}
},
"cpu": {
"user": "00:00:00",
"kernel": "00:00:00",
"total cpu": "00:00:00",
"breakdown": {
"query execution": "00:00:00",
"query planning": "00:00:00"
}
},
"memory": {
"peak_per_node": 2098656
},
"network": {
"inter_cluster_total_bytes": 250676,
"cross_cluster_total_bytes": 0
}
},
"input_dataset_statistics": {
"extents": {
"total": 1250,
"scanned": 1,
"scanned_min_datetime": "2024-01-08T07:13:13.6172552Z",
"scanned_max_datetime": "2024-01-08T07:13:13.6172552Z"
},
"rows": {
"total": 50000,
"scanned": 40
},
"rowstores": {
"scanned_rows": 0,
"scanned_values_size": 0
},
"shards": {
"queries_generic": 1,
"queries_specialized": 0
}
},
"dataset_statistics": [
{
"table_row_count": 10,
"table_size": 123654
}
],
"cross_cluster_resource_usage": {}
}
查询缓存的结果:此示例演示查询结果缓存中提供的查询。 请注意该节的存在 results_cache_origin
,该部分指示从以前缓存的查询结果中检索结果。 执行时间极快(0.0039999 秒)显示查询结果缓存的好处,因为不需要数据处理。 缓存包含有关填充缓存(client_request_id
)的原始请求的信息,以及最初执行时(started_on
)。 请注意,没有从区或行扫描数据,如节中的 input_dataset_statistics
零指示,确认直接从查询缓存检索结果。
{
"ExecutionTime": 0.0039999,
"resource_usage": {
"cache": {
"shards": {
"hot": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"cold": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"bypassbytes": 0
},
"results_cache_origin": {
"client_request_id": "KE.DF.RunQuery;95b6d241-e684-4a43-91c8-da0d6a854e3e",
"started_on": "2025-04-22T08:22:24.4719143Z"
}
},
"cpu": {
"user": "00:00:00.0156250",
"kernel": "00:00:00",
"total cpu": "00:00:00.0156250",
"breakdown": {
"query execution": "00:00:00.0156250",
"query planning": "00:00:00"
}
},
"memory": {
"peak_per_node": 53440160
},
"network": {
"inter_cluster_total_bytes": 13233,
"cross_cluster_total_bytes": 0
}
},
"input_dataset_statistics": {
"extents": {
"total": 0,
"scanned": 0,
"scanned_min_datetime": "0001-01-01T00:00:00.0000000Z",
"scanned_max_datetime": "0001-01-01T00:00:00.0000000Z"
},
"rows": {
"total": 0,
"scanned": 0
},
"rowstores": {
"scanned_rows": 0,
"scanned_values_size": 0
},
"shards": {
"queries_generic": 0,
"queries_specialized": 0
}
},
"dataset_statistics": [
{
"table_row_count": 10,
"table_size": 12121
}
],
"cross_cluster_resource_usage": {}
}
部分查询缓存(Per-Shard)的结果:此示例演示了受益于按分片级别缓存的查询,如本节所示 partial_query_results
。 缓存显示 1 次命中和 0 次未命中数,这意味着查询能够检索分片的预计算结果,而无需重新处理数据。 与完整的查询缓存示例不同,该 input_dataset_statistics
示例显示数据在技术上“已扫描”(59,066 行),但这可能是一个元数据作,因为实际计算是从缓存中检索到的。 请注意非常快的执行时间(0.0047499 秒),演示了部分查询缓存的性能优势。 对于重复访问具有相同筛选条件的相同数据分区的查询,每个分片缓存特别有用。
{
"QueryHash": "da3c6dc30e7b203d",
"ExecutionTime": 0.0047499,
"resource_usage": {
"cache": {
"shards": {
"hot": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"cold": {
"hitbytes": 0,
"missbytes": 0,
"retrievebytes": 0
},
"bypassbytes": 0
},
"partial_query_results": {
"hits": 1,
"misses": 0
}
},
"cpu": {
"user": "00:00:00.0156250",
"kernel": "00:00:00",
"total cpu": "00:00:00.0156250",
"breakdown": {
"query execution": "00:00:00.0156250",
"query planning": "00:00:00"
}
},
"memory": {
"peak_per_node": 1580848
},
"network": {
"inter_cluster_total_bytes": 27428,
"cross_cluster_total_bytes": 0
}
},
"input_dataset_statistics": {
"extents": {
"total": 1,
"scanned": 1,
"scanned_min_datetime": "2016-03-17T08:24:02.6259906Z",
"scanned_max_datetime": "2016-03-17T08:24:02.6259906Z"
},
"rows": {
"total": 59066,
"scanned": 59066
},
"rowstores": {
"scanned_rows": 0,
"scanned_values_size": 0
},
"shards": {
"queries_generic": 0,
"queries_specialized": 0
}
},
"dataset_statistics": [
{
"table_row_count": 10,
"table_size": 11473
}
],
"cross_cluster_resource_usage": {}
}