帮你快速理解、总结文档立即下载

OPERATOR_TRACE

最近更新时间:2026-08-20 15:23:32
我的收藏

功能

INFORMATION_SCHEMA.OPERATOR_TRACE 视图用于查询慢查询的算子级执行追踪记录。当查询执行时间超过慢查询阈值且 operator_trace 变量开启时,系统自动收集该查询的完整执行计划树信息(包括每个算子的类型、层级关系、耗时等),写入本地 CSV 日志文件。通过本视图可在线查询历史 trace 记录,辅助定位慢查询根因。
该视图基于 DuckDB 实现,通过读取实例数据目录下 operator_trace/ 目录中的 CSV 日志文件返回结果。CSV 字段分隔符为 \\x1F(ASCII Unit Separator),避免与查询数据中的逗号冲突。

适用版本

TDSQL Boundless V21.6.4.0及以上版本。

字段说明

字段名
类型
描述
name
VARCHAR(64)
算子名称,例如 Table scanNested loop inner joinIndex lookup 等,与 EXPLAIN FORMAT=TREE 输出中的算子名称一致。
trace_id
BIGINT UNSIGNED
该次 trace 的唯一标识 ID。同一次慢查询产生的所有算子记录共享相同的 trace_id
op_id
INT UNSIGNED
算子在执行计划树中的唯一编号,从0开始递增。
parent_id
INT UNSIGNED
父算子的 op_id。根算子的 parent_id 为0。通过 op_idparent_id 可还原完整的执行计划树结构。
start_time
TIMESTAMP
该算子开始执行的时间戳,精确到毫秒级,带时区信息。
duration_ns
BIGINT UNSIGNED
该算子的执行耗时,单位为纳秒(ns)。
extra
JSON
算子的额外信息,以 JSON 格式存储。包含估计行数(est_rows)、估计代价(est_cost)、实际行数(actual_rows)、循环次数(loops)等运行时统计信息。
说明:
extra 字段中的 JSON 内容因算子类型不同而异,常见键包括 est_rows(估计行数)、est_cost(估计代价)、actual_rows(实际行数)、loops(循环次数)等。
视图查询前建议先执行 FLUSH OPERATOR_TRACE_LOG 确保内存缓冲区中的日志已刷盘,否则最近写入的 trace 记录可能尚未可见。
同一次慢查询产生的多条记录通过相同的 trace_id 关联,结合 op_idparent_id 可还原执行计划树。

相关系统变量

变量名
级别
默认值
说明
operator_trace
SESSION
OFF
控制是否对慢查询收集 operator trace。关闭时零性能开销。
operator_trace_log_rotate_size
GLOBAL
104857600(100MB)
单个 trace 日志文件的大小上限(字节),超出后自动轮转。取值范围:4096 - 1073741824。
operator_trace_log_file_count
GLOBAL
10
保留的轮转日志文件数量上限,超出后自动清理最旧文件。

示例

# 1. 开启 operator trace 并设置慢查询阈值为 0(确保所有 SQL 都触发收集)
SET SESSION operator_trace = ON;
SET SESSION long_query_time = 0;

# 2. 执行目标查询
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id WHERE t1.val > 10;

# 3. 刷盘确保日志已写入文件
FLUSH OPERATOR_TRACE_LOG;

# 4. 查询最近一次慢查询的 operator trace
SELECT name, op_id, parent_id, duration_ns, extra
FROM information_schema.OPERATOR_TRACE
ORDER BY trace_id DESC, op_id ASC
LIMIT 10;
输出示例:
+-----------------------+-------+-----------+--------------+--------------------------------------------------------------+
| name | op_id | parent_id | duration_ns | extra |
+-----------------------+-------+-----------+--------------+--------------------------------------------------------------+
| Nested loop inner join| 0 | 0 | 12000000 | {"est_rows": 3, "est_cost": 5.2, "actual_rows": 3, "loops": 1} |
| Filter: (t1.val > 10) | 1 | 0 | 3000000 | {"est_rows": 5, "est_cost": 2.1, "actual_rows": 3, "loops": 1} |
| Table scan on t1 | 2 | 1 | 5000000 | {"est_rows": 5, "est_cost": 1.0, "actual_rows": 5, "loops": 1} |
| Index lookup on t2 | 3 | 0 | 8000000 | {"est_rows": 3, "est_cost": 3.1, "actual_rows": 3, "loops": 3} |
+-----------------------+-------+-----------+--------------+--------------------------------------------------------------+
4 rows in set (0.02 sec)
通过 parent_id 可还原执行计划树结构:根算子 Nested loop inner join(op_id=0)的两个子算子分别为 Filter(op_id=1,parent_id=0)和 Index lookup on t2(op_id=3,parent_id=0),Table scan on t1(op_id=2,parent_id=1)是 Filter 的子算子。