How can I find poor performing SQL queries in Oracle?
Oracle maintains statistics on shared SQL area and contains one row per SQL string(v$sqlarea). But how can we identify which one of them are badly performing?
Partitioning your data and creating local partitioned indexes can improve your query performance. On a partitioned table, each partition has its own set of index tables. Effectively, there are multiple indexes, but the results from each are combined as necessary to produce the final result set.
Use CASE instead of UPDATE UPDATE statement takes longer than CASE statement due to logging. On the other hand, CASE statement determines what needs to be updated and makes your SQL queries faster.
The Top SQL page displays SQL statements based on CPU time consumed, that are executed in the database. The SQL statement that consumes the maximum CPU time is right at the top, and the remaining statements continue in descending order based on CPU time.
In order to determine the SQL that may be contributing to the CPU usage, query the v$sqlarea view. This view contains statistics about SQL in the shared pool and its usage statistics. Also see my notes on 100% CPU consumption.
I found this SQL statement to be a useful place to start (sorry I can't attribute this to the original author; I found it somewhere on the internet):
SELECT * FROM (SELECT sql_fulltext, sql_id, elapsed_time, child_number, disk_reads, executions, first_load_time, last_load_time FROM v$sql ORDER BY elapsed_time DESC) WHERE ROWNUM < 10 /
This finds the top SQL statements that are currently stored in the SQL cache ordered by elapsed time. Statements will disappear from the cache over time, so it might be no good trying to diagnose last night's batch job when you roll into work at midday.
You can also try ordering by disk_reads and executions. Executions is useful because some poor applications send the same SQL statement way too many times. This SQL assumes you use bind variables correctly.
Then, you can take the sql_id
and child_number
of a statement and feed them into this baby:-
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', &child));
This shows the actual plan from the SQL cache and the full text of the SQL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With