在 Oracle 数据库中,要查看后台正在执行的 SQL 语句,可以通过查询动态性能视图(Dynamic Performance Views)或使用监控工具来实现。
1. 查询动态性能视图
(1) 查看当前活跃会话及其执行的 SQL
使用 v$session
和 v$sql
视图关联查询,获取正在执行的 SQL 信息:
SELECT
s.sid, s.serial#,
s.username,
s.status,
s.sql_id,
s.prev_sql_id,
q.sql_text,
s.program,
s.machine,
s.logon_time
FROM
v$session s
LEFT JOIN
v$sql q ON s.sql_id = q.sql_id
WHERE
s.status = 'ACTIVE' -- 筛选活跃会话
AND s.type != 'BACKGROUND' -- 排除后台进程
AND s.sql_id IS NOT NULL;
-
关键字段:
-
sql_id
:当前正在执行的 SQL 语句的唯一标识。 -
sql_text
:SQL 文本内容(可能被截断,完整内容需从v$sqlarea
获取)。 -
username
:执行 SQL 的数据库用户。 -
program
:发起 SQL 的客户端程序(如 JDBC、SQL Developer 等)。
-
(2) 查看长时间运行的 SQL 操作
使用 v$session_longops
监控长时间运行的操作(如全表扫描、索引重建等)
SELECT
sid, serial#,
opname,
target,
sofar,
totalwork,
ROUND(sofar / totalwork * 100, 2) AS progress_pct,
elapsed_seconds,
time_remaining
FROM
v$session_longops
WHERE
time_remaining > 0; -- 仅显示未完成的操作
SID
: 会话标识符。SERIAL#
: 会话序列号,与 SID 一起用于唯一标识一个会话。OPNAME
: 正在执行的操作名称。TARGET
: 操作目标对象名(如果适用)。TARGET_DESC
: 目标描述。SOFAR
: 到目前为止已完成的工作量。TOTALWORK
: 预估的总工作量。UNITS
: 工作量单位。START_TIME
: 操作开始的时间。LAST_UPDATE_TIME
: 上次更新此记录的时间。TIME_REMAINING
: 根据当前速度预估剩余时间(秒)。ELAPSED_SECONDS
: 自操作开始以来已经过去的秒数。CONTEXT
: 内部使用的上下文信息。MESSAGE
: 描述操作状态的消息。USERNAME
: 执行该操作的用户名。SQL_ADDRESS
: SQL 语句地址。SQL_HASH_VALUE
: SQL 语句的哈希值。SQL_ID
: SQL 语句的 ID。SQL_PLAN_HASH_VALUE
: SQL 计划的哈希值。QCINST_ID
: 并行查询协调器实例 ID(如果是并行操作)。QCSID
: 并行查询协调器的 SID(如果是并行操作)。QCSERIAL#
: 并行查询协调器的 SERIAL#(如果是并行操作)。
2. 查询 SQL 执行详细信息
(1) 通过 v$sqlarea
查看完整的 SQL 文本
SELECT
sql_id,
sql_text,
executions,
elapsed_time / 1000000 AS elapsed_sec,
cpu_time / 1000000 AS cpu_sec,
disk_reads,
buffer_gets
FROM
v$sqlarea
WHERE
sql_id = '<your_sql_id>'; -- 替换为实际的 sql_id
sql_id
: 每条SQL语句在数据库中的唯一标识符。这个ID可以帮助你识别和追踪特定的SQL语句。sql_text
: 这是完整的SQL语句文本。它显示了实际被执行的SQL语句内容。executions
: 表示这条SQL语句已经被执行了多少次。每次执行都会增加这个计数器。elapsed_time / 1000000 AS elapsed_sec
:elapsed_time
字段表示SQL语句执行所花费的总时间(微秒),通过除以1,000,000转换为秒,并将其重命名为elapsed_sec
以便更直观地理解时间单位。cpu_time / 1000000 AS cpu_sec
:cpu_time
字段表示SQL语句执行期间消耗的CPU时间(微秒),同样通过除以1,000,000转换为秒,并将其重命名为cpu_sec
。disk_reads
: 这个字段表示SQL语句执行过程中发生的物理读取次数,即从磁盘读取数据的次数。较高的值可能指示性能瓶颈。buffer_gets
: 表示逻辑读的数量,即SQL语句执行过程中从数据库缓冲区缓存中获取的数据块数量。高数值可能表明该语句对系统资源有较高需求。
(2) 查看 SQL 执行计划
通过 v$sql_plan
分析 SQL 的执行计划:
SELECT
*
FROM
v$sql_plan
WHERE
sql_id = '<your_sql_id>';
3. 使用 Oracle Enterprise Manager (OEM)
Oracle 提供的图形化工具 Enterprise Manager (OEM) 可以直观监控 SQL 执行:
-
登录 OEM 控制台。
-
导航到 Performance > SQL Monitoring。
-
查看实时 SQL 执行的详细信息,包括资源消耗、执行计划等。
4. 使用 Active Session History (ASH)
通过 v$active_session_history
查询历史活动会话信息(采样频率为每秒一次):
SELECT
sql_id,
session_id,
session_serial#,
sample_time,
event,
wait_time
FROM
v$active_session_history
WHERE
sql_id IS NOT NULL
ORDER BY
sample_time DESC;
快速定位问题 SQL
-- 查看消耗最多 CPU 的 SQL
SELECT
sql_id,
sql_text,
executions,
cpu_time / 1000000 AS cpu_sec,
elapsed_time / 1000000 AS elapsed_sec
FROM
v$sqlarea
ORDER BY
cpu_time DESC
FETCH FIRST 10 ROWS ONLY;
sql_id
: 每条SQL语句在数据库中的唯一标识符。通过这个ID可以追踪和分析特定的SQL语句。sql_text
: 这是SQL语句的实际文本内容,显示了被执行的SQL语句的具体内容。executions
: 表示这条SQL语句已经被执行了多少次。每次执行都会增加这个计数器,可以帮助你了解该语句的使用频率。cpu_time / 1000000 AS cpu_sec
:cpu_time
字段表示SQL语句执行期间消耗的CPU时间(微秒)。通过除以1,000,000将时间单位转换为秒,并将其重命名为cpu_sec
以便更直观地理解时间单位。这有助于评估SQL语句对CPU资源的占用情况。elapsed_time / 1000000 AS elapsed_sec
:elapsed_time
字段表示SQL语句执行所花费的总时间(微秒),通过除以1,000,000转换为秒,并将其重命名为elapsed_sec
。它包括等待时间和执行时间,可用于评估SQL语句的整体执行效率。