Some time ago, I wrote a note about using the packaged function dbms_xplan.display_cursor().
I’ve just seen a note on Rob van Wijk’s blog where he investigates many more format options that can be used with the function.
When I tried to add a comment to the blog listing a couple more of the options that I knew, I found that I couldn’t do so without creating a google or blogger account. So I’ve posted them here, and I’d be happy for someone with a suitable acccount to add them to Rob’s blog so that they’re all in the same place.
‘All’: Prints the Query block/Object Alias section, the Predicate information, and the Column Projection information after the basic plan.
‘Advanced’: as for ‘All’, but also include the Outline information (the set of hints that will reproduce the plan) and the peeked bind variables used to optimise the query.
‘Outline’: prints just the Outline information and the Predicate information after the basic plan.
I got the ‘Advanced’ one from one of the Oak Table members and guessed the ‘Outline’ one when I saw that it was possible to get the outline from the advanced output.
Update [Sept 2009] – I’ve just discovered another option (which should have been obvious really – especially given my comment about how I discovered the “outline” option)
‘Projection’: Print the “column projection” information. It’s a little obscure in places, but it tells you which columns have been passed to their parent by each line – and the size of those columns.
Update [Jan 2021] – A couple more options that are relevant to more recent versions of Oracle.
‘metrics’: Reports the directive id for any SQL Plan Directives that have been used to generate the plan. (See also MOS note 2390551.1
‘hint_report’, ‘hint_report_used’, ‘hint_report_unused’: the first reports the fate of all the hints you included in the SQL, the latter report only the used or unused (respectively) hint. Unused hints may also show the error that made a hint unusable. (See also Franck Pachot’s blog note on the hint report)
‘qbregistry’: reports the query block registry information – but it’s basically unreadable in 19c. Franck Pachot (again) has a not on an improvement in 20c which is the qbregistry_graph
‘adaptive’: reports the whole of an adaptive plan, marking inactive operations with a ‘-‘ and showing some “STATISTICS_COLLECTOR” operations
‘all_shards’: presumably supplies information about sharded objects or the handling of shards.
Oracle documentation explain about ‘ALL’ parameter, but not mentioned any thing about ‘Advanced’ and ‘Outline’. ORACLE_HOME/rdbms/admin/dbmsxpln.sql file has many good example for different procedure/ function and there parameters.
Nice to know 2 more parameter of display_cursor(), Thanks
Comment by Virag Sharma — March 6, 2008 @ 10:41 am GMT Mar 6,2008 |
Why do you suppose Oracle are Parameterising their functions in such an unusual way?
Are they deliberately attempting to make performance tuning the obfuscated art of a closed society?
Why not add these options as pseudo-boolean type parameters and atleast allow them to be revealed by “describe” – if keeping the documentation up to date is too onerous?
Comment by Basil — March 6, 2008 @ 2:56 pm GMT Mar 6,2008 |
Thanks Jonathan for letting me know and for making the list more complete.
I’ve added a small update section because of it.
Regards,
Rob.
Comment by Rob van Wijk — March 6, 2008 @ 10:36 pm GMT Mar 6,2008 |
Basil,
I don’t think they’re trying to make life difficult. It’s probably more a case of “and here’s another good idea” and a quick bolt-on. Once you start doing it one way, it’s hard to re-engineer.
Personally I’d love it if the Statspack code allowed you to select which bit of functionality went into the snapshot by setting boolean flags – as it is I have to hack the code to get just the bits I want. (But at least the source is there for hacking).
Comment by Jonathan Lewis — March 11, 2008 @ 6:34 am GMT Mar 11,2008 |
At least we have access to the spreport.sql script and can query the PERFSTAT schema
so that we can design modified versions of spreport.sql
Can’t do the same with awrrpt.sql at all ! It just calls a stored procedure which
“automagically” generates the report for us.
(BTW, have you used the “NO_OPTIONS=8” to “ENABLE_ADDM”, modifying awrrpti.sql ?
Hemant
Comment by Hemant K Chitale — March 12, 2008 @ 7:20 am GMT Mar 12,2008 |
Hi Jonathan,
Is there a way to check which step of a SQL execution plan currently being executed?
If we can get timing prediction on it that will be even better.
This will be very helpful for long running sqls with big execution plan and multi table joins etc.
Regards,
Darshan
Comment by Darshan — June 13, 2009 @ 7:27 pm BST Jun 13,2009 |
Darshan,
There are “approximations” that you can try.
If you know the steps of the plan you could keep checking V$session_wait for the session to check for calls related to disk I/O – this may give you some clues.
If you keep an eye on v$session_longops this may tell you about things like tablescans, sorts and other long operations – but again it’s just clues, not firm information. Gints Plivna has a good article on v$session_longops, and Hemant Chitale has a nice example of the potential traps.
But if you’re on 11g, there’s an option to do real-time monitoring of SQL statements. Greg Rahn wrote up an example of this last year.
Comment by Jonathan Lewis — June 14, 2009 @ 6:36 pm BST Jun 14,2009 |
Hi Jonathan,
Thanks for the knowledge and links you shared.
Do we have any information documented somewhere with examples on V$SQL_WORKAREA views? How one can leverage information in these.
I have seen these views are populated with some steps of the execution plan underway for a session id. Again it looks like it covers only few cases.
Regards,
Darshan
Comment by Darshan — June 16, 2009 @ 9:56 pm BST Jun 16,2009 |
Darshan,
The view v$sql_workarea is populated only for lines of execution plans (v$sql_plan) that relate to workarea usage, such as hash joins and sorts. If you’re running 9i and query v$sql_plan, you can do an outer join to v$sql_workarea to get information the most recent and cumulative use made of work areas. But in 10g it’s much easier to get this information with a call to dbms_xplan.display_cursor(). I’ve described this function in a few previous posts, commenting particularly on the hint /*+ gather_plan_statistics */ – but the work area information is always reported by this function – even if you haven’t used the hint.
Comment by Jonathan Lewis — June 20, 2009 @ 5:34 pm BST Jun 20,2009 |
outline is very useful, problem is how to make sense of the output produced by outline for a very complex query – the problem remains same , for example (allow me to post a long explain plan output I got for a complex query with outline option ).
Comment by Ajeet — January 18, 2012 @ 2:58 pm GMT Jan 18,2012 |
Ajeet,
I tried to make your output readable, but lost the predicate section while doing so.
If you want to try posting the example again, make sure you do “set trimspool on” before generating the output. Then start the output with “sourcecode” and end it with “/sourcecode” (but using square brackets instead of quote marks).
Comment by Jonathan Lewis — January 19, 2012 @ 8:28 am GMT Jan 19,2012 |
Jonathan
Thanks for your help, I am posting the pedicate information (after taking the output again using set trimspool on), as all other infomration as posted above are good.so I am posting only the predicate information. what i want to understand is the join order of the different tables, and anything which suggest that this plan is not optimal and how to really fix that. this will be a great help to everyone who has to read thru large plan outputs and then make sense of it.
Comment by Ajeet — January 19, 2012 @ 8:49 am GMT Jan 19,2012 |
The standard approach to a long plan is to think of it in pieces so, for example, the long chain of nested loop can be ignored to start with and your basic plan is this – which is much easier to understand.
Now we can go back to the cascading list of nested loops, and perhaps viewing it in isolation we decide that the hash join at line 42 should have been a nested loop into HR_ORGANIZATION_INFORMATION, So we search for the use_hash() hint that must be in the outline, and this is what we find:
Without the original SQL I was a little lucky that there was only one hash join, it made it easy to see that the table had an alias of O2, which allowed me to find the index hint on the table. The fact that there is a swap_join_inputs() hint tells me that the position of the table in the plan output will drop just below oe_order_headers_all (it looks like this plan came from 11g with the NLJ_Batching features showing up at this point), and all I need do is change the hint from use_hash to use_nl, and change the index definition to one that would allow me to do an efficient nested loop into the table.
It’s not difficult (usually – but ANSI can make it much harder), it just takes patience and practice.
Comment by Jonathan Lewis — January 26, 2012 @ 10:23 pm GMT Jan 26,2012 |
Jonathan,
Thanks for wonderful explanaation as always. I was trying to replace the
USE_HASH(@”SEL$426BD430″ “O2″@”SEL$5”)
with
USE_NL(USE_HASH(“O2″@”SEL$5”)
and I observed that I have to give the alias name as appeared in outline , If I give just use_nl(O2) , this hint was ingored.
O2 table is part of a view..is that the reason for this.
Kindly elobarate a bit on this.
Regards
Ajeet
Comment by Ajeet — January 28, 2012 @ 5:06 pm GMT Jan 28,2012 |
Ajeet,
See https://jonathanlewis.wordpress.com/2007/06/25/qb_name/
Comment by Jonathan Lewis — January 28, 2012 @ 8:13 pm GMT Jan 28,2012 |