在SQL*PLUS中应用AUTOTRACE REPORT

本文介绍在SQL*PLUS中应用AUTOTRACE REPORT。可通过AUTOTRACE系统变量配置报告,用户需被赋予PLUSTRACE角色并创建PLAN_TABLE表。报告涉及SQL语句执行计划和数据库统计两方面,设置set AUTOTRACE on后执行DML语句会生成报告,可用于语句分析和调优。
部署运行你感兴趣的模型镜像
 

SQL*PLUS中应用AUTOTRACE REPORT

 

作者:刘颖博

时间:2004-1-12

mailliuyingbo@126.com,请指正

 

转载请注明出处及作者

 

 

SQL*PLUS中,当你成功的执行一个DML语句,比如SELECT, DELETE, UPDATE ,INSERT,你可以通过SQL优化器和语句的执行统计自动的获得一份报告。这份报告对于DML语句的性能监控和调优都是很有用处的。这份报告就是本文要讲的AUTOTRACE 报告。

 

配置AUTOTRACE报告(Configuring the AUTOTRACE Report)

你可以通过以下的AUTOTRACE系统变量来配置AUTOTRACE报告. 如下表:

Table  AUTOTRACE Settings

AUTOTRACE Setting

Result

SET AUTOTRACE OFF

不能获得AUTOTRACE报告. 这是默认的.

SET AUTOTRACE ON EXPLAIN

仅仅显示优化器执行计划的AUTOTRACE报告

SET AUTOTRACE ON STATISTICS

仅仅显示SQL语句执行的统计结果的AUTOTRACE报告

SET AUTOTRACE ON

包括上面两项内容的AUTOTRACE报告

SET AUTOTRACE TRACEONLY

SET AUTOTRACE ON类似,所有的统计和数据都在,但不可以打印

 

其实,平时我们应该较多的就是SET AUTOTRACE ON 、SET AUTOTRACE OFF,谁会在乎多看一点AUTOTRACE报告呢! J

安装AUTOTRACE报告(Setups Required for the AUTOTRACE Report)

要用这个特性,用户必须被赋予PLUSTRACE角色,而PLUSTRACE角色需要DBA来赋予。另外,该用户必须创建PLAN_TABLE表。

I.                 首先创建PLUSTRACE角色并且赋给DBA:

CONNECT sys/sys’s password AS SYSDBA 
  
@$ORACLE_HOME/sqlplus/admin/plustrce.sql
  

II.              赋权限给用户

CONNECT / AS SYSDBA 
  

GRANT PLUSTRACE TO USER(预赋权的用户名);

 

这样,就可以在该用户下设置AUTOTRACE报告的显示与否了。

 

AUTOTRACE报告中涉及到的两个方面的内容

I.              SQL语句的执行计划

执行计划就是SQL优化器执行语句的查询执行顺序,每一行的执行计划都会有个行号,这个行号是连续的

II.          SQL语句的数据库统计

数据库统计是服务器记录的执行当前的这条语句所需要的系统资源等,主要包括下表的内容

Database Statistic Name

Description

recursive calls

Number of recursive calls generated at both the user and system level. Oracle maintains tables used for internal processing. When Oracle needs to make a change to these tables, it internally generates an internal SQL statement, which in turn generates a recursive call.

db block gets

Number of times a CURRENT block was requested.

consistent gets

Number of times a consistent read was requested for a block.

physical reads

Total number of data blocks read from disk. This number equals the value of "physical reads direct" plus all reads into buffer cache.

redo size

Total amount of redo generated in bytes.

bytes sent via SQL*Net to client

Total number of bytes sent to the client from the foreground processes.

bytes received via SQL*Net from client

Total number of bytes received from the client over Oracle Net.

SQL*Net roundtrips to/from client

Total number of Oracle Net messages sent to and received from the client.

sorts (memory)

Number of sort operations that were performed completely in memory and did not require any disk writes.

sorts (disk)

Number of sort operations that required at least one disk write.

rows processed

Number of rows processed during the operation.

 

简单使用的例子:

SQL> show user

USER is "SYS"

(注:当前是sysdba用户)

(注:创建PLUSTRACE角色并且赋给DBA)

SQL> start $ORACLE_HOME/sqlplus/admin/plustrce.sql

(注:start 等价于@)

SQL> drop role plustrace;

drop role plustrace

          *

ERROR at line 1:

ORA-01919: role 'PLUSTRACE' does not exist

 

 

SQL> create role plustrace;

 

Role created.

 

SQL>

SQL> grant select on v_$sesstat to plustrace;

 

Grant succeeded.

 

SQL> grant select on v_$statname to plustrace;

 

Grant succeeded.

SQL>

 

SQL> grant select on v_$session to plustrace;

 

Grant succeeded.

 

SQL> grant plustrace to dba with admin option;

 

Grant succeeded.

 

SQL>

SQL> set echo off

(注:赋角色plustrace给所需用户,这里用户是bill)

SQL> grant plustrace to bill;

 

Grant succeeded.

(注:接下来,用bill用户连接,测试AUTOTRACE)

SQL> connect bill/bill’s password;

Connected.

SQL> show user

USER is "BILL"

(注:为了看的清楚些,建立一个测试的表test,然后察看AUTOTRACE报告)

SQL>  create table test(id number(1));

 

Table created.

 

SQL> insert into test values(1);

 

1 row created.

 

SQL> /

 

1 row created.

 

SQL> /

 

1 row created.

 

SQL> /

 

1 row created.

 

SQL> commit;

 

Commit complete.

SQL> select * from test;

 

        ID

----------

         1

         1

         1

         1

 

SQL> set AUTOTRACE on

SQL> select * from test;

 

        ID

----------

         1

         1

         1

         1

 

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE

   1    0   TABLE ACCESS (FULL) OF 'TEST'

 

 

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          4  consistent gets

          0  physical reads

          0  redo size

        547  bytes sent via SQL*Net to client

        655  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

4         rows processed

 

上面我们就可以看到,当你设置了set AUTOTRACE on后,执行相应的DML语句,就会有相应的AUTOTRACE报告出现了。当然,我们的这种设置是session级别的。这样,我们就可以根据AUTOTRACE报告对我们执行的DML语句进行分析和调优了!

 

参考:

oracle的官方文档(otn.oracle.com)

 

您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

<think>我们被要求比较两个SQL查询在Oracle数据库中的执行效率。根据引用[3],我们知道带有DISTINCT、UNION等操作的SQL会触发排序操作,影响性能。同时,引用[1]提到Oracle对子查询做了优化,有时子查询可能快于多表查询。引用[2]则提到Hint的使用注意事项。因此,我们可以通过以下方法来对比两个SQL查询的执行效率:###方法1:使用`EXPLAIN PLAN`分析执行计划通过查看执行计划,可以了解每个查询的步骤和消耗资源情况。 ```sql--为第一个查询生成执行计划EXPLAIN PLANFOR<第一个查询语句>; --查看执行计划SELECT* FROMTABLE(DBMS_XPLAN.DISPLAY); --为第二个查询生成执行计划EXPLAIN PLANFOR<第二个查询语句>; --查看执行计划SELECT* FROMTABLE(DBMS_XPLAN.DISPLAY); ```**分析重点**: -比较两个计划的`Cost`值(相对成本) -观察是否使用了索引(全表扫描`FULLTABLE SCAN`效率低) -注意排序操作(`SORT`)和连接方式(`HASH JOIN`、`NESTEDLOOPS`等)###方法2:使用`AUTOTRACE`跟踪实际执行统计在SQL*PlusSQL Developer中启用自动跟踪: ```sqlSET AUTOTRACE ON``` 然后分别运行两个查询,将显示: -实际执行时间-逻辑读(consistent gets) -物理读(physical reads) -排序操作(sorts (memory/disk)) ###方法3:使用`SQL_TRACE`和`TKPROF`进行详细分析1.启用会话级跟踪:```sqlALTER SESSION SETSQL_TRACE =TRUE;```2.分别执行两个查询3.关闭跟踪:```sqlALTER SESSION SETSQL_TRACE =FALSE;```4.使用TKPROF工具格式化跟踪文件:```bashtkprof<trace_file_name.trc> <output_file.txt>```**分析输出**: -每个查询的CPU时间、经过时间-执行次数、解析次数-磁盘I/O和内存读###方法4:使用`V$SQL`视图获取历史执行统计```sqlSELECTsql_id,executions,elapsed_time,cpu_time,disk_reads,buffer_getsFROM V$SQLWHEREsql_textLIKE'%<部分查询文本>%' ```**注意**:需确保查询已执行过且仍在共享池中###性能对比要点1. **执行时间**:实际消耗时间(elapsed_time)是最直观的指标2.**资源消耗**:-逻辑读(buffer_gets):内存访问次数,越低越好-物理读(disk_reads):磁盘I/O次数,应尽量减少3. **排序操作**:引用[3]指出排序是资源密集型操作,需关注`sorts (memory)`和`sorts (disk)` 4. **执行计划稳定性**:检查是否使用了最优索引和连接方式###优化提示-若发现子查询效率更高,可优先采用(参考引用[1]) -使用Hint调整执行计划时,注意引用[2]的规则(需在子查询内单独指定Hint)-避免不必要的排序操作(如`UNION`改为`UNION ALL`,除非需要去重) >**典型场景**:当比较一个多表连接查询和一个使用子查询的等效查询时,Oracle可能对子查询有更好的优化(如子查询展开、物化视图等)[^1]。§§相关问题§§1.如何解读Oracle执行计划中的`Cost`值? 2.在Oracle中如何强制使用特定索引? 3. `UNION`和`UNIONALL`在性能上有什么区别? 4.如何减少SQL查询的物理读操作?5.为什么有时候逻辑读很高但执行时间很短?</think>在 Oracle 数据库中对比两个 SQL 查询的执行效率,可通过以下专业方法实现: ### 一、执行计划分析(最常用方法) 使用 `EXPLAIN PLAN` 查看查询优化器选择的执行路径: ```sql -- 为第一个查询生成执行计划 EXPLAIN PLAN FOR SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM employees WHERE department_id = 10; -- 为第二个查询生成执行计划 EXPLAIN PLAN FOR SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM employees WHERE job_id = 'MANAGER'; -- 查看比较结果 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); ``` **关键指标对比**: 1. **Cost 值**:优化器预估的相对资源消耗(越低越好) 2. **Rows 列**:预估返回行数 vs 实际行数(差异大表示统计信息不准) 3. **访问方式**: - `FULL TABLE SCAN`(全表扫描)通常比 `INDEX RANGE SCAN`(索引扫描)慢 - 注意 `HASH JOIN` 与 `NESTED LOOPS` 的效率差异[^1] ### 二、实时性能追踪 使用 `SQL*Plus AUTOTRACE` 获取实际运行时统计: ```sql SET AUTOTRACE TRACEONLY STATISTICS -- 不输出结果只显示统计 -- 执行第一个查询 SELECT * FROM orders WHERE order_date > SYSDATE - 30; -- 执行第二个查询 SELECT * FROM orders WHERE customer_id = 1005; ``` **关键对比指标**: ```diff | 统计项 | 查询1 | 查询2 | 说明 | |----------------|-------|-------|--------------------------| | consistent gets| 150 | 25 | 内存逻辑读(越低越好)[^3] | | physical reads | 30 | 2 | 物理磁盘读(越低越好) | | sorts (memory) | 0 | 3 | 内存排序次数[^3] | | elapsed time | 0.15s | 0.02s | 实际执行时间 | ``` ### 三、高级性能诊断工具 1. **SQL Monitor 实时监控**(需 Diagnostic Pack 许可) ```sql -- 启用监控 ALTER SESSION SET STATISTICS_LEVEL = ALL; -- 执行查询后查看报告 SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(sql_id=>'abc123') FROM dual; ``` 2. **AWR 报告分析**(历史性能) ```sql SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML( db_id => NULL, inst_num => NULL, bid => 12345, -- 开始快照ID eid => 12346 -- 结束快照ID )); ``` 检查报告中的 "SQL ordered by Elapsed Time" 部分 ### 四、精准耗时对比 使用 `DBMS_UTILITY.GET_TIME` 微秒级计时: ```sql DECLARE v_start NUMBER; v_sql1 VARCHAR2(1000) := 'SELECT COUNT(*) FROM large_table WHERE col1 = 1'; v_sql2 VARCHAR2(1000) := 'SELECT COUNT(*) FROM large_table WHERE col2 = ''A'''; BEGIN v_start := DBMS_UTILITY.GET_TIME; EXECUTE IMMEDIATE v_sql1; DBMS_OUTPUT.PUT_LINE('查询1耗时: ' || (DBMS_UTILITY.GET_TIME - v_start)/100 || '秒'); v_start := DBMS_UTILITY.GET_TIME; EXECUTE IMMEDIATE v_sql2; DBMS_OUTPUT.PUT_LINE('查询2耗时: ' || (DBMS_UTILITY.GET_TIME - v_start)/100 || '秒'); END; ``` ### 五、优化器提示强制特定执行计划 通过 Hint 控制执行路径进行对比测试: ```sql -- 测试全表扫描 SELECT /*+ FULL(emp) */ * FROM emp WHERE deptno = 10; -- 测试索引扫描 SELECT /*+ INDEX(emp idx_emp_dept) */ * FROM emp WHERE deptno = 10; ``` > **注意**:Hint 必须使用表别名(如引用[2]所述),若表有别名需写 `/*+ INDEX(e idx_emp_dept) */`[^2] ### 最佳实践建议 1. **预热缓存**:首次执行前运行 `ALTER SYSTEM FLUSH BUFFER_CACHE;` 避免缓存干扰 2. **多次执行**:取 5 次执行的平均值,消除首次解析开销 3. **关注逻辑读**:`consistent gets` 比执行时间更能反映真实资源消耗 4. **检查排序操作**:如引用[3]指出,`DISTINCT/UNION/GROUP BY` 会触发高成本排序[^3] 5. **绑定变量**:避免硬解析影响测试公平性 > **案例**:某性能优化中,通过对比发现 `UNION`(需两次排序)比 `UNION ALL` 多消耗 300% 逻辑读,改用 `UNION ALL` 后性能提升 4 倍[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值