1. Background
When sql optimizes, we often use execution plans, such as Navicat or plsql explain plans. In fact, the result is only an estimated value, so it will cause the test environment to execute quickly and the production environment to be slow.
As shown below:
The execution plan obtained using AUTOTRACE or EXPLAIN PLAN FOR comes from PLAN_TABLE. PLAN_TABLE is a session-level temporary table, the execution plan inside is not the real execution plan of SQL, it is only estimated by the optimizer.
The real execution plan should not be estimated, it should be actually executed. The SQL executed execution plan exists in the shared pool, specifically in the data dictionary VS QLPLAN, the execution plan with A − T ime comes from V SQL_PLAN, the execution plan with A-Time comes from VSQLPLAN, with The execution plan with A-Time comes from VSQL_PLAN, which is the real execution plan, and the execution plan obtained through AUTOTRACE and EXPLAIN PLAN FOR is only the execution plan estimated by the optimizer. (Note 1)
2. So how to get the real execution plan?
First, you must have access to the dynamic performance view, you can use the following statement to authorize
grant select any dictionary to QAS_R_BIZ;
After having the authority, divide into the following steps to go (super administrator does not need)
2.1 Execute the following statement
alter session set statistics_level = all;
(This step is valid for the current session window, it can be omitted, explained below)
2.2 Execute the sql to be optimized;
select /* gather_plan_statistics */ R.RU_ID AS ruId,
R.MU_ID AS muId,
R.RU_NAME AS ruShortName,
D.YW_DM AS YWDM,
D.yws AS YWDMCOUNT
from T_REGIONAL_UNIT r
LEFT JOIN T_MANAGE_UNIT m
on r.MU_ID = m.MU_ID
left join (select YW_DM, sum(YW_DM_COUNT) as yws, SWJGDM
from T_DAILY_SELF_SERVICE_HALL_YWS
where SNAPSHOT_DATE between
TO_DATE('2020-01-14 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND
TO_DATE('2020-12-14 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
group by YW_DM, SWJGDM) D
on m.MU_CODE = D.SWJGDM
where 1 = 1
and r.parent_ID = 10000
order by r.display_index, D.YW_DM
If you do not do the previous step, you need to add /+ gather_plan_statistics / in the statement.
2.3 Find out the SQL ID of the executed statement, for example:
select * from v$sql where sql_text like '%gather_plan_statistics%'
The result is as follows
2.4 Find out the execution plan based on SQL ID
select * from table(dbms_xplan.display_cursor('3ayyrp8bkzmb6',null,'allstats last')); The
effect is as follows,
Copy and paste it to notepad++, in order to display all the query results, remember to click the Get Last Page button, click the upper left corner to select all.
Paste into notepad or notepad++, the effect is as follows
You can see that there are more fields such as A-Rows and A-Time.
Starts represents the number of executions of this operation.
E-Rows represents the number of rows estimated by the optimizer. That is, Rows in the ordinary execution plan.
A-Rows represents the actual number of rows.
A-Time represents the total accumulated time. Different from the ordinary execution plan, the Time in the ordinary execution plan is fake, while the A-Time is real.
Buffers means accumulated logical reads.
Reads means accumulated physical reads. The
real execution plan provides real information about SQL execution, including A-Time (real time), A-Rows (real row number), Starts (step execution times), etc. For non-database developers, it is very intuitive and convenient.