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 |
compute |
结构 | 表示用于运行语句的计算资源类型以及相关资源 ID(如适用)的结构。
type 值将是 WAREHOUSE 或 SERVERLESS_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 |
字符串 | 语句类型。 例如:ALTER、COPY 和 INSERT。 |
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 |
查看记录的查询配置文件
要基于查询历史记录表中的记录导航到查询的查询配置文件,请执行以下操作:
- 找到相关记录,然后复制记录的
statement_id。 - 请参考记录的
workspace_id以确保您登录的工作区与记录相同。 - 单击
工作区边栏中的查询历史记录。
- 在“语句 ID”字段中,粘贴记录上的
statement_id。 - 单击查询的名称。 此时将显示查询指标的概述。
- 单击“查看查询配置文件”。
了解 query_source 列
该 query_source 列包含语句执行中涉及的 Azure Databricks 实体的一组唯一标识符。
query_source如果该列包含多个 ID,则表示语句执行是由多个实体触发的。 例如,作业结果可能会触发调用 SQL 查询的警报。 在此示例中,将填充所有三个 ID 到 query_source。 此列的值不按执行顺序排序。
可能的查询源包括:
- alert_id:从警报触发的语句
- sql_query_id:在此 SQL 编辑器 会话中执行的语句
- dashboard_id:从仪表板执行的语句
- legacy_dashboard_id:在旧仪表板中执行的语句
- genie_space_id:从 Genie 空间执行的语句
- notebook_id:从笔记本执行的语句
- job_info.job_id:在作业中执行的语句
- job_info.job_run_id:从作业运行执行的语句
- job_info.job_task_run_id:在作业任务运行中执行的语句
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_id和legacy_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_id和alert_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_PATH 和 LOOKUP_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;