如何查看查询转换器在 Oracle 中生成的查询
How can I see the query that the query transformer produced in Oracle
据我所知,查询转换器会尽可能将我们的查询转换为更好的查询。所以我执行的查询和最后执行的查询数据库可以不一样
如何查看数据库执行的最终查询?我的意思是查询转换器的结果。
Oracle 提供了一个工具,可以让您查看查询的执行计划。这可以深入了解所执行的优化,并提供机会根据成本指标手动优化查询。 Oracle 不会生成修改后的查询供您检查。
EXPLAIN PLAN 文档在这里 https://docs.oracle.com/cd/B19306_01/server.102/b14211/ex_plan.htm#g42231
要查看优化器使用的转换查询,您应该使用 10053 跟踪。但是执行计划更方便,通常也足够好。
示例架构
举个简单的例子,这个模式包含两个简单的 table,第二个 table 中的每一行都必须存在于第一个 table.
中
--drop table test2;
--drop table test1;
create table test1(a number primary key);
create table test2(a number primary key references test1(a));
我们想要生成一个简单的查询,其中转换后的查询将不同于原始查询。为此,下面的查询有一个不必要的连接。由于存在内部联接,并且 TEST2 中的每一行在 TEST1 中必须且仅存在一次,因此 Oracle 不需要进行联接。相反,Oracle 只需要读取单个 table 或来自 TEST2.
的索引
select count(*) new_name_for_hard_parse_01
from test1
join test2 on test1.a = test2.a;
10053 跟踪
要找到优化器使用的精确查询,您需要生成 10053 跟踪。例如:
alter session set events '10053 trace name context forever, level 1';
select count(*) new_name_for_hard_parse_02
from test1
join test2 on test1.a = test2.a;
alter session set events '10053 trace name context off';
(请注意我如何为列使用不同的名称。您需要更改查询并强制进行硬解析。否则,Oracle 可能会简单地重新使用现有的执行计划而不会生成跟踪。)
稍等一下,该文件将显示在某处的跟踪目录中。根据版本和配置,该文件可能位于 USER_DUMP_DEST 或 DIAGNOSTIC_DEST 下的子目录中。例如,在我的 PC 上它是文件 D:\app\jon\virtual\diag\rdbms\orcl12\orcl12\trace\orcl12_ora_22576.trc
打开文件并查找如下部分:
...
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT COUNT(*) "NEW_NAME_FOR_HARD_PARSE_02" FROM "JHELLER"."TEST2" "TEST2"
....
跟踪文件解释了不同的转换并显示了最终查询。
但您几乎从不想使用 Oracle 跟踪文件。跟踪文件很不方便,命令没有记录并且不能很好地工作,而且您不会总是能够访问服务器文件系统。对于 99.9% 的 Oracle 性能调优,跟踪都是浪费时间。
执行计划
执行计划是确定查询运行方式的更快方法,这可能是您感兴趣的内容。
explain plan for
select count(*) new_name_for_hard_parse_01
from test1
join test2 on test1.a = test2.a;
select * from table(dbms_xplan.display);
结果:
Plan hash value: 4187894267
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 0 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| SYS_C009744 | 1 | 0 (0)| 00:00:01 |
------------------------------------------------------------------------
执行计划显示了如何只使用一个对象。没有说明用了join elimination,还得自己去推断。
如果您的 Oracle 软件版本有许可,您可以尝试使用 TKPROF 实用程序。
要遵循的步骤:
alter session set tracefile_identifier= Test;
alter session set sql_trace = true;
select * from "Your query";
alter session set sql_trace = false;
select value from v$diag_info where name = ‘Diag Trace’;
cd "path from the above query"
tkprof "required filename.trc" try_ex.txt
并且在使用 tkprof 创建的跟踪文件中提供了详细信息。
有关 tkprof 的更多信息,请查看 Oracle 文档。
据我所知,查询转换器会尽可能将我们的查询转换为更好的查询。所以我执行的查询和最后执行的查询数据库可以不一样
如何查看数据库执行的最终查询?我的意思是查询转换器的结果。
Oracle 提供了一个工具,可以让您查看查询的执行计划。这可以深入了解所执行的优化,并提供机会根据成本指标手动优化查询。 Oracle 不会生成修改后的查询供您检查。
EXPLAIN PLAN 文档在这里 https://docs.oracle.com/cd/B19306_01/server.102/b14211/ex_plan.htm#g42231
要查看优化器使用的转换查询,您应该使用 10053 跟踪。但是执行计划更方便,通常也足够好。
示例架构
举个简单的例子,这个模式包含两个简单的 table,第二个 table 中的每一行都必须存在于第一个 table.
中--drop table test2;
--drop table test1;
create table test1(a number primary key);
create table test2(a number primary key references test1(a));
我们想要生成一个简单的查询,其中转换后的查询将不同于原始查询。为此,下面的查询有一个不必要的连接。由于存在内部联接,并且 TEST2 中的每一行在 TEST1 中必须且仅存在一次,因此 Oracle 不需要进行联接。相反,Oracle 只需要读取单个 table 或来自 TEST2.
的索引select count(*) new_name_for_hard_parse_01
from test1
join test2 on test1.a = test2.a;
10053 跟踪
要找到优化器使用的精确查询,您需要生成 10053 跟踪。例如:
alter session set events '10053 trace name context forever, level 1';
select count(*) new_name_for_hard_parse_02
from test1
join test2 on test1.a = test2.a;
alter session set events '10053 trace name context off';
(请注意我如何为列使用不同的名称。您需要更改查询并强制进行硬解析。否则,Oracle 可能会简单地重新使用现有的执行计划而不会生成跟踪。)
稍等一下,该文件将显示在某处的跟踪目录中。根据版本和配置,该文件可能位于 USER_DUMP_DEST 或 DIAGNOSTIC_DEST 下的子目录中。例如,在我的 PC 上它是文件 D:\app\jon\virtual\diag\rdbms\orcl12\orcl12\trace\orcl12_ora_22576.trc
打开文件并查找如下部分:
...
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT COUNT(*) "NEW_NAME_FOR_HARD_PARSE_02" FROM "JHELLER"."TEST2" "TEST2"
....
跟踪文件解释了不同的转换并显示了最终查询。
但您几乎从不想使用 Oracle 跟踪文件。跟踪文件很不方便,命令没有记录并且不能很好地工作,而且您不会总是能够访问服务器文件系统。对于 99.9% 的 Oracle 性能调优,跟踪都是浪费时间。
执行计划
执行计划是确定查询运行方式的更快方法,这可能是您感兴趣的内容。
explain plan for
select count(*) new_name_for_hard_parse_01
from test1
join test2 on test1.a = test2.a;
select * from table(dbms_xplan.display);
结果:
Plan hash value: 4187894267
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 0 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| SYS_C009744 | 1 | 0 (0)| 00:00:01 |
------------------------------------------------------------------------
执行计划显示了如何只使用一个对象。没有说明用了join elimination,还得自己去推断。
如果您的 Oracle 软件版本有许可,您可以尝试使用 TKPROF 实用程序。
要遵循的步骤:
alter session set tracefile_identifier= Test;
alter session set sql_trace = true;
select * from "Your query";
alter session set sql_trace = false;
select value from v$diag_info where name = ‘Diag Trace’;
cd "path from the above query"
tkprof "required filename.trc" try_ex.txt
并且在使用 tkprof 创建的跟踪文件中提供了详细信息。 有关 tkprof 的更多信息,请查看 Oracle 文档。