343 lines
9.9 KiB
MySQL
343 lines
9.9 KiB
MySQL
|
|
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
|
||
|
|
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
|
||
|
|
|
||
|
|
--------------------------------------------------------------------------------
|
||
|
|
-- File name: exafriendly.sql (report non-exadata-friendly SQL and their stats)
|
||
|
|
--
|
||
|
|
-- Purpose: This script is a collection of queries against ASH, which will
|
||
|
|
-- report and drill down into workloads which don't use Exadata smart
|
||
|
|
-- scanning and are doing buffered full table scans or random single
|
||
|
|
-- block reads instead. It uses the 11g new ASH columns
|
||
|
|
-- (SQL_PLAN_OPERATION, SQL_PLAN_OPTIONS) which give SQL plan line
|
||
|
|
-- level activity breakdown.
|
||
|
|
--
|
||
|
|
-- Note that this script is not a single SQL performance diagnosis tool,
|
||
|
|
-- for looking into a single SQL, use the SQL Monitoring report. This
|
||
|
|
-- exafriendly.sql script is aimed for giving you a high-level
|
||
|
|
-- bird's-eye view of "exadata-friendiness" of your workloads, so you'd
|
||
|
|
-- detect systemic problems and drill down where needed.
|
||
|
|
--
|
||
|
|
-- Usage: @exafriendly.sql <ash_data_source>
|
||
|
|
--
|
||
|
|
-- Examples: @exafriendly.sql gv$active_session_history
|
||
|
|
--
|
||
|
|
-- @exafriendly.sql "dba_hist_active_sess_history WHERE snap_time > SYSDATE-1"
|
||
|
|
--
|
||
|
|
-- Author: Tanel Poder ( http://blog.tanelpoder.com | tanel@tanelpoder.com )
|
||
|
|
--
|
||
|
|
-- Copyright: (c) 2012 All Rights Reserved
|
||
|
|
--
|
||
|
|
--
|
||
|
|
-- Other: I strongly recommend you to read through the script to understand
|
||
|
|
-- what it's doing and how the drilldown happens. You likely need
|
||
|
|
-- to customize things (or at least adjust filters) when you diagnose
|
||
|
|
-- stuff in your environment.
|
||
|
|
--
|
||
|
|
--------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
set timing on tab off verify off linesize 999 pagesize 5000 trimspool on trimout on null ""
|
||
|
|
|
||
|
|
COL wait_class FOR A20
|
||
|
|
COL event FOR A40
|
||
|
|
COL plan_line FOR A40
|
||
|
|
COL command_name FOR A15
|
||
|
|
COL pct FOR 999.9
|
||
|
|
|
||
|
|
define ash=&1
|
||
|
|
|
||
|
|
SELECT MAX(sample_time) - MIN(sample_time)
|
||
|
|
FROM &ash
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report the top active SQL statements regardless of their CPU usage/wait event breakdown
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_id
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
WHERE
|
||
|
|
session_type = 'FOREGROUND'
|
||
|
|
GROUP BY
|
||
|
|
sql_id
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report the top session state/wait class breakdown
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
session_state,wait_class
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
GROUP BY
|
||
|
|
session_state,wait_class
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report the top session state/wait event breakdown (just like TOP-5 Timed Events in AWR)
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
session_state,wait_class,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
GROUP BY
|
||
|
|
session_state,wait_class,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report the top SQL waiting for buffered single block reads
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
session_state,wait_class,event,sql_id
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
WHERE
|
||
|
|
session_state = 'WAITING'
|
||
|
|
AND event = 'cell single block physical read'
|
||
|
|
GROUP BY
|
||
|
|
session_state,wait_class,event,sql_id
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report the top SQL waiting for buffered single block reads the most (with sampled execution count)
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,event,sql_id
|
||
|
|
, COUNT(DISTINCT(sql_exec_id)) noticed_executions
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
WHERE
|
||
|
|
session_state = 'WAITING'
|
||
|
|
AND event = 'cell single block physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,event,sql_id
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report what kind of SQL execution plan operations, executed by which user wait for buffered single block reads the most
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,u.username,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash a
|
||
|
|
, dba_users u
|
||
|
|
WHERE
|
||
|
|
a.user_id = u.user_id
|
||
|
|
AND session_state = 'WAITING'
|
||
|
|
AND event = 'cell single block physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,event,u.username
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report what kind of execution plan operations wait for buffered single block reads
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
WHERE
|
||
|
|
session_state = 'WAITING'
|
||
|
|
AND event = 'cell single block physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
|
||
|
|
PROMPT Report what kind of execution plan operations wait for buffered single block reads - against which schemas
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,p.object_owner,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM
|
||
|
|
v$active_session_history a
|
||
|
|
, v$sql_plan p
|
||
|
|
WHERE
|
||
|
|
a.sql_id = p.sql_id
|
||
|
|
AND a.sql_child_number = p.child_number
|
||
|
|
AND a.sql_plan_line_id = p.id
|
||
|
|
AND session_state = 'WAITING'
|
||
|
|
AND event = 'cell single block physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,p.object_owner,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report what kind of execution plan operations wait for buffered single block reads - against which objects
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,p.object_owner,p.object_name,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM
|
||
|
|
v$active_session_history a
|
||
|
|
, v$sql_plan p
|
||
|
|
WHERE
|
||
|
|
a.sql_id = p.sql_id
|
||
|
|
AND a.sql_child_number = p.child_number
|
||
|
|
AND a.sql_plan_line_id = p.id
|
||
|
|
AND session_state = 'WAITING'
|
||
|
|
AND event = 'cell single block physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,p.object_owner,p.object_name,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report which SQL command type consumes the most time (broken down by wait class)
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
command_name,session_state,wait_class
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash, v$sqlcommand
|
||
|
|
WHERE &ash..sql_opcode = v$sqlcommand.command_type
|
||
|
|
GROUP BY
|
||
|
|
command_name,session_state,wait_class
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report what kind of execution plan operations wait for buffered multiblock reads the most
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM
|
||
|
|
&ash
|
||
|
|
WHERE
|
||
|
|
session_state = 'WAITING'
|
||
|
|
AND event = 'cell multiblock physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report what kind of execution plan operations wait for buffered multiblock reads - against which objects
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,p.object_owner,p.object_name,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM
|
||
|
|
v$active_session_history a
|
||
|
|
, v$sql_plan p
|
||
|
|
WHERE
|
||
|
|
a.sql_id = p.sql_id
|
||
|
|
AND a.sql_child_number = p.child_number
|
||
|
|
AND a.sql_plan_line_id = p.id
|
||
|
|
AND session_state = 'WAITING'
|
||
|
|
AND event = 'cell multiblock physical read'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,p.object_owner,p.object_name,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|
||
|
|
PROMPT Report any PARALLEL full table scans which use buffered reads (in-memory PX)
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_id
|
||
|
|
, sql_plan_operation||' '||sql_plan_options plan_line
|
||
|
|
, CASE WHEN qc_session_id IS NULL THEN 'SERIAL' ELSE 'PARALLEL' END is_parallel
|
||
|
|
-- , px_flags
|
||
|
|
, session_state
|
||
|
|
, wait_class
|
||
|
|
, event
|
||
|
|
, COUNT(*)
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
WHERE
|
||
|
|
sql_plan_operation = 'TABLE ACCESS'
|
||
|
|
AND sql_plan_options = 'STORAGE FULL'
|
||
|
|
AND session_state = 'WAITING'
|
||
|
|
AND event IN ('cell single block physical read', 'cell multiblock physical read', 'cell list of blocks physical read')
|
||
|
|
AND qc_session_id IS NOT NULL -- is a px session
|
||
|
|
GROUP BY
|
||
|
|
sql_id
|
||
|
|
, sql_plan_operation||' '||sql_plan_options
|
||
|
|
, CASE WHEN qc_session_id IS NULL THEN 'SERIAL' ELSE 'PARALLEL' END --is_parallel
|
||
|
|
-- , px_flags
|
||
|
|
, session_state
|
||
|
|
, wait_class
|
||
|
|
, event
|
||
|
|
ORDER BY COUNT(*) DESC
|
||
|
|
)
|
||
|
|
WHERE rownum <= 20
|
||
|
|
/
|
||
|
|
|
||
|
|
DEF sqlid=4mpjt2rhwd1p4
|
||
|
|
PROMPT Report a single SQL_ID &sqlid
|
||
|
|
|
||
|
|
SELECT * FROM (
|
||
|
|
SELECT
|
||
|
|
sql_plan_operation||' '||sql_plan_options plan_line,session_state,event
|
||
|
|
, SUM(1) seconds
|
||
|
|
, ROUND(RATIO_TO_REPORT(COUNT(*)) OVER () * 100, 1) pct
|
||
|
|
FROM &ash
|
||
|
|
WHERE
|
||
|
|
sql_id = '&sqlid'
|
||
|
|
GROUP BY
|
||
|
|
sql_plan_operation||' '||sql_plan_options,session_state,event
|
||
|
|
ORDER BY
|
||
|
|
seconds DESC
|
||
|
|
)
|
||
|
|
WHERE
|
||
|
|
rownum <= 10
|
||
|
|
/
|
||
|
|
|