如何可靠地获取查询的 SQL_ID
How to reliably get the SQL_ID of a query
我知道这似乎是一个简单的问题 - 您可能认为存在现有答案。然而...
了解我希望它在性能上合理,因此它允许在没有太多开销的情况下记录每个执行的单个查询 - 或者至少是大的查询。
我的第一个想法是这个查询:
select sid,serial#,prev_sql_id from v$session where audsid=userenv('sessionid');
我的想法是,如果我 运行 在我的目标查询之后立即执行此操作,我将通过 prev_sql_id.
捕获正确的 sql_id
但是......我不是......我得到了一个不同的SQL......显然在我的目标SELECT语句和prev_sql_id
的查询之间,有些东西否则 运行。在我的例子中,审计是启用的,我正在捕获插入 SYS.AUD$
table。不好。
因为我这次尝试的主要目的是捕获查询的执行计划(因为它是由共享池执行和捕获的),我认为我可以简单地 运行 这个查询:
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
文档指出,使用 NULL
SQL_ID
作为参数,它将 运行 最近查询 运行 的解释计划。我希望这会解决早期的问题。但是......我得到了完全相同的插入 SYS.AUD$
table.
的计划
您可能会说,好吧,那么只需在您的查询中添加一条注释即可轻松捕获 SQL_ID
,如下所示:
SELECT /* SQL: 1234-12' */ FROM DUAL;
然后我可以尝试找到 SQL_ID 如下:
SELECT * FROM V$SQLAREA WHERE sql_text like '%SQL: 1234-12%';
这将给我几个可能的候选者,其中还包括 V$SQLAREA
查询本身。这里的问题是我需要 运行domize 每个查询 运行,这会导致我总是有一个硬解析。
我已经尝试过其他解决方案,但我的成本要高得多。我试图搜索其他解决方案。他们似乎都在某种程度上落后了。
相关文章:
- Blog: Displaying and Reading the exception plans for a SQL Statement
- Oracle queries executed by a session
你可以使用新的 SQL*Plus option:
SET FEEDBACK ON SQL_ID;
SQL_ID returns the sql_id for the SQL or PL/SQL statements that are executed. The sql_id will be assigned to the predefined variable _SQL_ID. You can use this predefined variable to debug the SQL statement that was executed. The variable can be used like any other predefined variable, such as _USER and _DATE.
SQL> SET FEEDBACK ON SQL_ID
SQL> SELECT * FROM DUAL;
D
-
X
1 row selected.
SQL_ID: a5ks9fhw2v9s1
--
SQL> SELECT sql_text FROM v$sql WHERE sql_id = '&_sql_id';
SQL_TEXT
-----------------------------------------------------
SELECT * FROM DUAL
1 row selected.
我知道这似乎是一个简单的问题 - 您可能认为存在现有答案。然而...
了解我希望它在性能上合理,因此它允许在没有太多开销的情况下记录每个执行的单个查询 - 或者至少是大的查询。
我的第一个想法是这个查询:
select sid,serial#,prev_sql_id from v$session where audsid=userenv('sessionid');
我的想法是,如果我 运行 在我的目标查询之后立即执行此操作,我将通过 prev_sql_id.
捕获正确的sql_id
但是......我不是......我得到了一个不同的SQL......显然在我的目标SELECT语句和prev_sql_id
的查询之间,有些东西否则 运行。在我的例子中,审计是启用的,我正在捕获插入 SYS.AUD$
table。不好。
因为我这次尝试的主要目的是捕获查询的执行计划(因为它是由共享池执行和捕获的),我认为我可以简单地 运行 这个查询:
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
文档指出,使用 NULL
SQL_ID
作为参数,它将 运行 最近查询 运行 的解释计划。我希望这会解决早期的问题。但是......我得到了完全相同的插入 SYS.AUD$
table.
您可能会说,好吧,那么只需在您的查询中添加一条注释即可轻松捕获 SQL_ID
,如下所示:
SELECT /* SQL: 1234-12' */ FROM DUAL;
然后我可以尝试找到 SQL_ID 如下:
SELECT * FROM V$SQLAREA WHERE sql_text like '%SQL: 1234-12%';
这将给我几个可能的候选者,其中还包括 V$SQLAREA
查询本身。这里的问题是我需要 运行domize 每个查询 运行,这会导致我总是有一个硬解析。
我已经尝试过其他解决方案,但我的成本要高得多。我试图搜索其他解决方案。他们似乎都在某种程度上落后了。
相关文章:
- Blog: Displaying and Reading the exception plans for a SQL Statement
- Oracle queries executed by a session
你可以使用新的 SQL*Plus option:
SET FEEDBACK ON SQL_ID;
SQL_ID returns the sql_id for the SQL or PL/SQL statements that are executed. The sql_id will be assigned to the predefined variable _SQL_ID. You can use this predefined variable to debug the SQL statement that was executed. The variable can be used like any other predefined variable, such as _USER and _DATE.
SQL> SET FEEDBACK ON SQL_ID
SQL> SELECT * FROM DUAL;
D
-
X
1 row selected.
SQL_ID: a5ks9fhw2v9s1
--
SQL> SELECT sql_text FROM v$sql WHERE sql_id = '&_sql_id';
SQL_TEXT
-----------------------------------------------------
SELECT * FROM DUAL
1 row selected.