不能。ASH不区分数据来源,external table的IO等待表现为direct path read等通用事件,且不保存文件路径和格式等DDL元数据,需关联v$sql、dba_external_tables等视图才能定位根因。

ASH能直接看到external table的IO等待吗
不能。ASH(v$active_session_history)本身不区分数据来源,它只记录会话在采样时刻的等待事件、SQL ID、堆栈和绑定变量等上下文。external table的读取行为最终会归为底层OS文件IO,在ASH中表现为direct path read、db file sequential read(若使用了临时段缓存)或external table read(Oracle 12c+ 新增,但仅限部分场景,且默认不启用)。更常见的是direct path read——这其实是external table通过Direct Path机制绕过SGA读取文件时的真实等待。
所以关键不是“ASH能不能看到”,而是:你得知道该查什么事件、过滤什么条件、结合哪些关联视图。
查external table加载慢,ASH里要过滤哪几个关键字段
直接在v$active_session_history中执行以下筛选逻辑才有效:
- 用
sql_id关联v$sql确认语句确实含SELECT FROM ext_.*或INSERT INTO ... SELECT FROM ext_.* - 过滤
event IN ('direct path read', 'external table read', 'db file sequential read'),优先看direct path read的p1(file#)、p2(block#)是否稳定集中在某几个值——说明卡在特定文件偏移 - 加
session_type = 'FOREGROUND'排除后台进程干扰 - 限定时间范围:
sample_time BETWEEN SYSDATE - 1/24 AND SYSDATE(最近1小时),避免ASH滚动过快丢失细节
别漏掉blocking_session字段——external table加载虽不锁表,但若与DML事务共用同一临时表空间或遭遇enq: TS – contention,也会被阻塞。
为什么ASH里看不到external table的文件路径和格式信息
因为ASH不保存DDL元数据。external table的定义(比如LOCATION ('/data/sales.csv')、RECORDS DELIMITED BY NEWLINE)存在dba_external_locations和dba_external_tables里。ASH只记录运行时行为,不反查对象定义。
所以必须手动关联:
- 从ASH拿到
sql_id→ 查v$sql.sql_text定位external table别名(如FROM ext_sales_csv) - 用别名去查
dba_external_tables.table_name→ 得到default_directory_name - 再用
default_directory_name查dba_directories→ 拿到真实OS路径 - 最后结合
dba_external_columns确认字段类型和分隔符——隐式类型转换(如把字符串当NUMBER解析)会导致单行处理变慢,ASH里只体现为CPU高、direct path read等待少但elapsed time长
ASH分析external table的典型误判点
最容易错把现象当根因:
-
direct path read等待时间长 ≠ 磁盘慢:可能是CSV文件有超长行、嵌套引号未闭合,导致Oracle解析器反复回溯,实际是CPU瓶颈,ASH里session_state = 'ON CPU'占比高,但新手只盯着wait event排序 - 看到大量
PGA memory allocation等待:external table默认不走PGA缓存,除非显式指定PREPROCESSOR或用了ORACLE_LOADER的ACCESS PARAMETERS中LOAD子句——此时应查v$process_memory而非ASH - 用
ASH report(awrddrpt.sql)看汇总:它会把external table的IO合并进“Other IO”,丢失文件粒度,必须用原始v$active_session_history查
真正卡点往往藏在“没等待”的地方:解析CSV结构、字符集转换(比如AL32UTF8里遇到无效字节)、正则匹配字段分隔符——这些全在CPU上跑,ASH里只有ON CPU状态,没有对应event可抓。











