快速得到SQL带A-Time时间的执行计划的小技巧

使用spool把结果输出到文件,然后直接去文件查看执行计划即可

得到带时间的执行计划的方法有两种:

1、在会话设置参数statistics_level=all

altersessionsetstatistics_level=all;执行SQLselect*fromtable(dbms_xplan.display_cursor(null,null,'allstatslast'));

2、在语句中使用hint(/*+ gather_plan_statistics */),然后查出这个SQL的SQL_ID,然后再去查询执行计划

执行SQLselect/*+gather_plan_statistics*/count(*)fromtest;查询SQL的SQL_IDselectsql_id,sql_textfromv$sqlwheresql_textlike'%/*+gather_plan_statistics*/%';查看执行计划select*fromtable(dbms_xplan.display_cursor('sql_id',null,'allstats'));

以上的两种方式都可以得到带时间的执行计划。

但是用这样的方式去查看执行计划,有一个弊端:必须等到SQL语句的全部的记录在屏幕输出,然后才可以查看执行计划。

为了不需要等待SQL执行完,然后才可以查看执行计划;以及不需要在屏幕输出SQL的执行结果刷屏,

可以采用把SQL的结果以及执行计划输出到文件,然后去文件查看执行计划。

!!!注意:!!!

使用spool把结果输出到文件,是把查询结果输出到文件,包含真实的数据,因此需要慎重考虑,

是否可以采取这样的方式进行查询。

测试:

需要查看一条SQL的带时间的执行计划

方法1、

设置会话参数altersessionsetstatistics_level=all;执行SQLselect/*+index(t1idx_t1_c1)*/*fromt1wherec1<=90000;需要等待执行完SQL,然后才可以查询查看执行计划select*fromtable(dbms_xplan.display_cursor(null,null,'allstatslast'));

方法2、

执行带hint的SQLselect/*+gather_plan_statisticsindex(t1idx_t1_c1)*/*fromt1wherec1<=90000;需要等待执行完SQL查询该SQL对应的SQL_IDselectsql_id,sql_textfromv$sqlwheresql_textlike'%/*+gather_plan_statistics*/%';查看执行计划(根据这条SQL的SQL_ID查询)select*fromtable(dbms_xplan.display_cursor('sql_id',null,'allstats'));

方法3、

先编写脚本

vitest.sqlsetline200pages999settimingonsettermoutoffspool/home/oracle/test.txtaltersessionsetstatistics_level=all;select/*+index(t1idx_t1_c1)*/*fromt1wherec1<=90000;select*fromtable(dbms_xplan.display_cursor(null,null,'allstatslast'));spooloff-----------参数解释:setline200pages999设置输出格式settimingon设置时间settermoutoff设置不让脚本的内容在屏幕输出spool/home/oracle/test.txt打开spool;并且设置输出文件的位置以及名称spooloff关闭spool,否则会一直把sqlplus里的内容写道test.txt文件中登录到sqlplussqlplus/assysdba(或者执行该SQL的用户)执行该脚本@/home/oracle/test.txt查看文件中的执行计划90000rowsselected.Elapsed:00:00:25.90PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------SQL_IDcaumajpb0jz24,childnumber1-------------------------------------select/*+index(t1idx_t1_c1)*/*fromt1wherec1<=90000Planhashvalue:4200789634------------------------------------------------------------------------------------------------------------|Id|Operation|Name|Starts|E-Rows|A-Rows|A-Time|Buffers|Reads|------------------------------------------------------------------------------------------------------------|0|SELECTSTATEMENT||1||90000|00:00:14.07|456K|315K||1|TABLEACCESSBYINDEXROWID|T1|1|90001|90000|00:00:14.07|456K|315K||*2|INDEXRANGESCAN|IDX_T1_C1|1|90001|90000|00:00:00.08|6187|0|------------------------------------------------------------------------------------------------------------PredicateInformation(identifiedbyoperationid):---------------------------------------------------2-access("C1"<=90000)19rowsselected.Elapsed:00:00:00.08

等执行完毕去查看该文件即可,在文件最低端可以看到执行计划,省去了中间刷屏的时间,

但是产生了一个带有数据的文件,当记录很多时,最好不要使用,

此方法只作为小技巧,需要看具体情况去判断是否使用该方法。