2026-03-12 20:23:15
This commit is contained in:
184
csierra/cs_mark_sql_hot.sql
Normal file
184
csierra/cs_mark_sql_hot.sql
Normal file
@@ -0,0 +1,184 @@
|
||||
----------------------------------------------------------------------------------------
|
||||
--
|
||||
-- File name: cs_mark_sql_hot.sql
|
||||
--
|
||||
-- Purpose: Use DBMS_SHARED_POOL.markhot to reduce contention during high concurency hard parse
|
||||
--
|
||||
-- Author: Carlos Sierra
|
||||
--
|
||||
-- Version: 2021/11/05
|
||||
--
|
||||
-- Usage: Execute connected to PDB.
|
||||
--
|
||||
-- Enter SQL_ID when requested.
|
||||
--
|
||||
-- Example: $ sqlplus / as sysdba
|
||||
-- SQL> @cs_mark_sql_hot.sql
|
||||
--
|
||||
-- Notes: Developed and tested on 19c
|
||||
--
|
||||
-- https://jonathanlewis.wordpress.com/2017/10/02/markhot/
|
||||
--
|
||||
-- When a statement (through its “full_hash_value”) is marked as hot
|
||||
-- an extra value visible as the property column in v$db_object_cache
|
||||
-- is set to a value that seems to be dependent on the process id of the
|
||||
-- session attempting to execute the statement, and this value is used as
|
||||
-- an extra component in calculating a new full_hash_value (which leads
|
||||
-- to a new hash_value and sql_id).
|
||||
-- With a different full_hash_value the same text generates a new parent
|
||||
-- cursor which is (probably) going to be associated with a new library
|
||||
-- cache hash bucket and latch.
|
||||
-- The property value for the original parent cursor is set to “HOT”,
|
||||
-- and the extra copies become “HOTCOPY1”, “HOTCOPY2” and so on.
|
||||
-- Interestingly once an object is marked as HOT and the first HOTCOPYn
|
||||
-- has appeared the original version may disappear from v$sql while still
|
||||
-- existing in v$db_object_cache.
|
||||
--
|
||||
---------------------------------------------------------------------------------------
|
||||
--
|
||||
@@cs_internal/cs_primary.sql
|
||||
@@cs_internal/cs_cdb_warn.sql
|
||||
@@cs_internal/cs_set.sql
|
||||
@@cs_internal/cs_def.sql
|
||||
@@cs_internal/cs_file_prefix.sql
|
||||
--
|
||||
DEF cs_script_name = 'cs_mark_sql_hot';
|
||||
--
|
||||
PRO
|
||||
PRO 1. Selective SQL Text Substring: (e.g.: /* getMaxTransactionCommitID */)
|
||||
DEF sql_text_substring = '&1.';
|
||||
UNDEF 1;
|
||||
--
|
||||
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
|
||||
--
|
||||
@@cs_internal/cs_signature.sql
|
||||
--
|
||||
@@cs_internal/cs_spool_head.sql
|
||||
PRO SQL> @&&cs_script_name..sql "&&sql_text_substring."
|
||||
@@cs_internal/cs_spool_id.sql
|
||||
--
|
||||
PRO SQL_TEXT_STR : "&&sql_text_substring."
|
||||
--
|
||||
COL hot NEW_V hot FOR 9999;
|
||||
COL cold NEW_V cold FOR 9999;
|
||||
COL hash_value FOR 9999999999;
|
||||
COL sql_text FOR A80 TRUNC;
|
||||
--
|
||||
PRO
|
||||
PRO BEFORE
|
||||
PRO ~~~~~~
|
||||
WITH
|
||||
s AS (
|
||||
SELECT /*+ MATERIALIZE NO_MERGE */
|
||||
DISTINCT con_id, sql_id, hash_value, address, sql_text
|
||||
FROM v$sql
|
||||
WHERE &&cs_con_id. <> 1 -- executed on PDB and not on CDB$ROOT
|
||||
AND con_id = &&cs_con_id.
|
||||
AND '&&sql_text_substring.' IS NOT NULL
|
||||
AND sql_text LIKE '%&&sql_text_substring.%'
|
||||
AND sql_text NOT LIKE '%MATERIALIZE%' -- exclude SQL like this one!
|
||||
AND object_status = 'VALID'
|
||||
AND is_obsolete = 'N'
|
||||
AND is_shareable = 'Y'
|
||||
AND ROWNUM >= 1 /* MATERIALIZE */
|
||||
)
|
||||
SELECT c.full_hash_value,
|
||||
SUM(CASE WHEN c.property IS NOT NULL THEN 1 ELSE 0 END) AS hot,
|
||||
SUM(CASE WHEN c.property IS NULL THEN 1 ELSE 0 END) AS cold,
|
||||
s.sql_id, s.hash_value, s.address, s.sql_text
|
||||
FROM s, v$db_object_cache c
|
||||
WHERE c.con_id = s.con_id
|
||||
AND c.hash_value = s.hash_value
|
||||
AND c.addr = s.address
|
||||
AND c.name = s.sql_text
|
||||
AND c.namespace = 'SQL AREA'
|
||||
AND c.type = 'CURSOR'
|
||||
AND c.status = 'VALID'
|
||||
GROUP BY
|
||||
c.full_hash_value, s.sql_id, s.hash_value, s.address, s.sql_text
|
||||
ORDER BY
|
||||
c.full_hash_value, s.sql_id, s.hash_value, s.address, s.sql_text
|
||||
/
|
||||
--
|
||||
PRO
|
||||
PRO SUMMARY
|
||||
PRO ~~~~~~~
|
||||
WITH
|
||||
s AS (
|
||||
SELECT /*+ MATERIALIZE NO_MERGE */
|
||||
DISTINCT con_id, sql_id, hash_value, address, sql_text
|
||||
FROM v$sql
|
||||
WHERE &&cs_con_id. <> 1 -- executed on PDB and not on CDB$ROOT
|
||||
AND con_id = &&cs_con_id.
|
||||
AND '&&sql_text_substring.' IS NOT NULL
|
||||
AND sql_text LIKE '%&&sql_text_substring.%'
|
||||
AND sql_text NOT LIKE '%MATERIALIZE%' -- exclude SQL like this one!
|
||||
AND object_status = 'VALID'
|
||||
AND is_obsolete = 'N'
|
||||
AND is_shareable = 'Y'
|
||||
AND ROWNUM >= 1 /* MATERIALIZE */
|
||||
)
|
||||
SELECT SUM(CASE WHEN c.property IS NOT NULL THEN 1 ELSE 0 END) AS hot,
|
||||
SUM(CASE WHEN c.property IS NULL THEN 1 ELSE 0 END) AS cold
|
||||
FROM s, v$db_object_cache c
|
||||
WHERE c.con_id = s.con_id
|
||||
AND c.hash_value = s.hash_value
|
||||
AND c.addr = s.address
|
||||
AND c.name = s.sql_text
|
||||
AND c.namespace = 'SQL AREA'
|
||||
AND c.type = 'CURSOR'
|
||||
AND c.status = 'VALID'
|
||||
/
|
||||
--
|
||||
PRO
|
||||
PAUSE Hit "return" to continue; or "control-c" then "return" to exit:
|
||||
--
|
||||
PRO
|
||||
PRO MAKE HOT (IF COLD > 0 AND HOT = 0)
|
||||
PRO ~~~~~~~~
|
||||
SET SERVEROUT ON;
|
||||
BEGIN
|
||||
IF TO_NUMBER(NVL(TRIM('&&cold.'), '0')) > 0 AND TO_NUMBER(NVL(TRIM('&&hot.'), '0')) = 0 THEN -- sql has not been marked as hot
|
||||
FOR i IN (
|
||||
WITH
|
||||
s AS (
|
||||
SELECT /*+ MATERIALIZE NO_MERGE */
|
||||
DISTINCT con_id, sql_id, hash_value, address, sql_text
|
||||
FROM v$sql
|
||||
WHERE &&cs_con_id. <> 1 -- executed on PDB and not on CDB$ROOT
|
||||
AND con_id = &&cs_con_id.
|
||||
AND '&&sql_text_substring.' IS NOT NULL
|
||||
AND sql_text LIKE '%&&sql_text_substring.%'
|
||||
AND sql_text NOT LIKE '%MATERIALIZE%' -- exclude SQL like this one!
|
||||
AND object_status = 'VALID'
|
||||
AND is_obsolete = 'N'
|
||||
AND is_shareable = 'Y'
|
||||
AND ROWNUM >= 1 /* MATERIALIZE */
|
||||
)
|
||||
SELECT DISTINCT full_hash_value
|
||||
FROM s, v$db_object_cache c
|
||||
WHERE c.con_id = s.con_id
|
||||
AND c.hash_value = s.hash_value
|
||||
AND c.addr = s.address
|
||||
AND c.name = s.sql_text
|
||||
AND c.namespace = 'SQL AREA'
|
||||
AND c.type = 'CURSOR'
|
||||
AND c.status = 'VALID'
|
||||
AND c.property IS NULL -- COLD
|
||||
)
|
||||
LOOP
|
||||
DBMS_OUTPUT.put_line('MARKHOT:'||i.full_hash_value);
|
||||
DBMS_SHARED_POOL.markhot(hash => i.full_hash_value, namespace => 0);
|
||||
END LOOP;
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
SET SERVEROUT OFF;
|
||||
--
|
||||
PRO
|
||||
PRO SQL> @&&cs_script_name..sql "&&sql_text_substring."
|
||||
--
|
||||
@@cs_internal/cs_spool_tail.sql
|
||||
@@cs_internal/cs_undef.sql
|
||||
@@cs_internal/cs_reset.sql
|
||||
--
|
||||
Reference in New Issue
Block a user