查询历史记录系统表参考

Important

此系统表处于公共预览阶段

本文包含有关查询历史记录系统表的信息,包括表架构的大纲。

表路径:此系统表位于 system.query.history

使用查询历史记录表

查询历史记录表包含使用 SQL 仓库或无服务器计算运行的笔记本作业的查询记录。 该表包含你访问该表所在同一区域中所有工作区的帐户级记录。

默认情况下,只有管理员有权访问该系统表。 如果要与用户或组共享表的数据,Databricks 建议为每个用户或组创建动态视图。 请参阅创建动态视图

查询历史记录系统表架构

查询历史记录表使用以下架构:

列名称 数据类型 Description Example
account_id 字符串 帐户的 ID。 11e22ba4-87b9-4cc2
-9770-d10b894b7118
workspace_id 字符串 运行查询的工作区的 ID。 1234567890123456
statement_id 字符串 唯一标识语句执行的 ID。 你可以使用此 ID 在查询历史记录 UI 中查找语句执行。 7a99b43c-b46c-432b
-b0a7-814217701909
session_id 字符串 Spark 会话 ID。 01234567-cr06-a2mp
-t0nd-a14ecfb5a9c2
execution_status 字符串 语句终止状态。 可能的值包括:
  • FINISHED:执行成功
  • FAILED:执行失败,出现随附错误消息中所述失败的原因
  • CANCELED:执行已取消
FINISHED
compute 结构 表示用于运行语句的计算资源类型以及相关资源 ID(如适用)的结构。 type 值将是 WAREHOUSESERVERLESS_COMPUTE {
type: WAREHOUSE,
cluster_id: NULL,
warehouse_id: ec58ee3772e8d305
}
executed_by_user_id 字符串 运行语句的用户的 ID。 2967555311742259
executed_by 字符串 运行语句的用户的电子邮件地址或用户名。 example@databricks.com
statement_text 字符串 SQL 语句的文本。 如果已配置客户管理的密钥,则 statement_text 为空。 由于存储限制,较长的语句文本值会进行压缩。 即使使用压缩,也可能达到字符限制。 SELECT 1
statement_type 字符串 语句类型。 例如:ALTERCOPYINSERT SELECT
error_message 字符串 描述错误情况的消息。 如果已配置客户管理的密钥,则 error_message 为空。 [INSUFFICIENT_PERMISSIONS]
Insufficient privileges:
User does not have
permission SELECT on table
'default.nyctaxi_trips'.
client_application 字符串 运行语句的客户端应用程序。 例如:Databricks SQL 编辑器、Tableau 和 Power BI。 此字段源自客户端应用程序提供的信息。 虽然预期值会随时间保持不变,但无法保证。 Databricks SQL Editor
client_driver 字符串 用于连接到 Databricks 以运行语句的连接器。 例如:Databricks SQL Driver for Go、Databricks ODBC Driver、Databricks JDBC Driver。 Databricks JDBC Driver
cache_origin_statement_id 字符串 对于从缓存中提取的查询结果,此字段包含最初将结果插入缓存的查询的语句 ID。 如果查询结果不是从缓存中获取的,此字段将包含查询语句自身的ID。 01f034de-5e17-162d
-a176-1f319b12707b
total_duration_ms bigint 语句的总执行时间(以毫秒为单位,不包括结果提取时间)。 1
waiting_for_compute_duration_ms bigint 等待计算资源配置的时间(以毫秒为单位)。 1
waiting_at_capacity_duration_ms bigint 在队列中等待可用计算容量的时间(以毫秒为单位)。 1
execution_duration_ms bigint 执行语句的时间(以毫秒为单位)。 1
compilation_duration_ms bigint 加载元数据和优化语句的时间(以毫秒为单位)。 1
total_task_duration_ms bigint 所有任务持续时间的总和(以毫秒为单位)。 此时间表示跨所有节点的所有核心运行查询所花费的总时间。 如果多个任务并行执行,它可能明显长于挂钟持续时间。 如果任务等待可用节点,它可能短于挂钟持续时间。 1
result_fetch_duration_ms bigint 执行完成后获取语句结果所花费的时间(以毫秒为单位)。 1
start_time 时间戳 Databricks 收到请求的时间。 时区信息记录在值的末尾,其中 +00:00 表示 UTC。 2022-12-05T00:00:00.000+0000
end_time 时间戳 语句执行结束的时间(不包括结果获取时间)。 时区信息记录在值的末尾,其中 +00:00 表示 UTC。 2022-12-05T00:00:00.000+00:00
update_time 时间戳 语句最后收到进度更新的时间。 时区信息记录在值的末尾,其中 +00:00 表示 UTC。 2022-12-05T00:00:00.000+00:00
read_partitions bigint 修剪后读取的分区数。 1
pruned_files bigint 已修剪的文件数。 1
read_files bigint 修剪后读取的文件数。 1
read_rows bigint 语句读取的总行数。 1
produced_rows bigint 语句返回的总行数。 1
read_bytes bigint 语句读取的数据总大小(以字节为单位)。 1
read_io_cache_percent int 从 IO 缓存读取的持久性数据字节百分比。 50
from_result_cache boolean TRUE 表示语句结果是从缓存中获取的。 TRUE
spilled_local_bytes bigint 执行语句时临时写入磁盘的数据大小(以字节为单位)。 1
written_bytes bigint 写入云对象存储的持久性数据大小(以字节为单位)。 1
written_rows bigint 写入到云对象存储的持久性数据的行数。 1
written_files bigint 写入云对象存储的持久性数据的文件数。 1
shuffle_read_bytes bigint 通过网络发送的数据总量(以字节为单位)。 1
query_source 结构 包含表示参与此语句执行的 Databricks 实体(如作业、笔记本或仪表板)的键值对的结构。 此字段仅记录 Databricks 实体。 {
alert_id: 81191d77-184f-4c4e-9998-b6a4b5f4cef1,
sql_query_id: null,
dashboard_id: null,
notebook_id: null,
job_info: {
job_id: 12781233243479,
job_run_id: null,
job_task_run_id: 110373910199121
},
legacy_dashboard_id: null,
genie_space_id: null
}
query_parameters 结构 包含参数化查询中使用的命名参数和位置参数的结构。 命名参数表示为键值对,将参数名称映射到值。 位置参数表示为一个列表,其中索引指示参数位置。 一次只能存在一种类型(命名或位置)。 {
named_parameters: {
"param-1": 1,
"param-2": "hello"
},
pos_parameters: null,
is_truncated: false
}
executed_as 字符串 用于运行语句的用户或服务主体的名称。 example@databricks.com
executed_as_user_id 字符串 用于运行语句的用户或服务主体的 ID。 2967555311742259

查看记录的查询配置文件

要基于查询历史记录表中的记录导航到查询的查询配置文件,请执行以下操作:

  1. 找到相关记录,然后复制记录的 statement_id
  2. 请参考记录的 workspace_id 以确保您登录的工作区与记录相同。
  3. 单击“历史记录”图标。工作区边栏中的查询历史记录
  4. 在“语句 ID”字段中,粘贴记录上的 statement_id
  5. 单击查询的名称。 此时将显示查询指标的概述。
  6. 单击“查看查询配置文件”

了解 query_source 列

query_source 列包含语句执行中涉及的 Azure Databricks 实体的一组唯一标识符。

query_source如果该列包含多个 ID,则表示语句执行是由多个实体触发的。 例如,作业结果可能会触发调用 SQL 查询的警报。 在此示例中,将填充所有三个 ID 到 query_source。 此列的值不按执行顺序排序。

可能的查询源包括:

query_source 的有效组合

以下示例显示如何根据查询的运行方式填充query_source列:

  • 在作业运行期间执行的查询包含已填充的 job_info 结构:

    {
    alert_id: null,
    sql_query_id: null,
    dashboard_id: null,
    notebook_id: null,
    job_info: {
    job_id: 64361233243479,
    job_run_id: null,
    job_task_run_id: 110378410199121
    },
    legacy_dashboard_id: null,
    genie_space_id: null
    }

  • 来自旧版仪表板的查询包含 sql_query_idlegacy_dashboard_id

    {
    alert_id: null,
    sql_query_id: 7336ab80-1a3d-46d4-9c79-e27c45ce9a15,
    dashboard_id: null,
    notebook_id: null,
    job_info: null,
    legacy_dashboard_id: 1a735c96-4e9c-4370-8cd7-5814295d534c,
    genie_space_id: null
    }

  • 来自警报的查询包含 sql_query_idalert_id

    {
    alert_id: e906c0c6-2bcc-473a-a5d7-f18b2aee6e34,
    sql_query_id: 7336ab80-1a3d-46d4-9c79-e27c45ce9a15,
    dashboard_id: null,
    notebook_id: null,
    job_info: null,
    legacy_dashboard_id: null,
    genie_space_id: null
    }

  • 来自仪表板的查询包含 dashboard_id,但不包含 job_info

    {
    alert_id: null,
    sql_query_id: null,
    dashboard_id: 887406461287882,
    notebook_id: null,
    job_info: null,
    legacy_dashboard_id: null,
    genie_space_id: null
    }

从元存储具体化查询历史记录

以下代码可用于创建每小时、每天或每周运行的作业,以从元存储具体化查询历史记录。 相应地调整 HISTORY_TABLE_PATHLOOKUP_PERIOD_DAYS 变量。

from delta.tables import *
from pyspark.sql.functions import *
from pyspark.sql.types import *

HISTORY_TABLE_PATH = "jacek.default.history"
# Adjust the lookup period according to your job schedule
LOOKUP_PERIOD_DAYS = 1

def table_exists(table_name):
    try:
        spark.sql(f"describe table {table_name}")
        return True
    except Exception:
        return False

def save_as_table(table_path, df, schema, pk_columns):
    deltaTable = (
        DeltaTable.createIfNotExists(spark)
        .tableName(table_path)
        .addColumns(schema)
        .execute()
    )

    merge_statement = " AND ".join([f"logs.{col}=newLogs.{col}" for col in pk_columns])

    result = (
        deltaTable.alias("logs")
        .merge(
            df.alias("newLogs"),
            f"{merge_statement}",
        )
        .whenNotMatchedInsertAll()
        .whenMatchedUpdateAll()
        .execute()
    )
    result.show()

def main():
    df = spark.read.table("system.query.history")
    if table_exists(HISTORY_TABLE_PATH):
        df = df.filter(f"update_time >= CURRENT_DATE() - INTERVAL {LOOKUP_PERIOD_DAYS} days")
    else:
        print(f"Table {HISTORY_TABLE_PATH} does not exist. Proceeding to copy the whole source table.")

    save_as_table(
        HISTORY_TABLE_PATH,
        df,
        df.schema,
        ["workspace_id", "statement_id"]
    )

main()

分析表的受欢迎程度,包括缓存的查询

表世系系统表不会从结果缓存中发出查询结果的条目。 因此,必须将查询历史记录表与表世系系统表联接,以在分析中包含缓存的查询。

例如,以下查询用于检索在过去7天内执行时间超过一小时的查询的表:

SELECT
    t.source_table_full_name,
    COUNT(*) AS num_of_queries_over_hour
FROM
    system.query.history h
    INNER JOIN system.access.table_lineage t
        ON t.statement_id = h.cache_origin_statement_id
WHERE
    h.total_duration_ms > 3600000
    AND t.event_time > CURRENT_TIMESTAMP() - INTERVAL 7 DAYS
    AND t.source_table_full_name IS NOT NULL
GROUP BY t.source_table_full_name
ORDER BY 2 DESC;