-- ############################################################################################# -- -- %Purpose: Flush Shared Pool when it reaches 60-70% of it's capacity -- -- Use: SYS-User -- -- ############################################################################################# -- -- On a recent project we had a problem where performance would start -- acceptable at the beginning of the day and by mid-day would be -- totally unacceptable. Investigation showed that the third party -- application that ran on top of the Oracle database was generating -- ad hoc SQL without using bind variables. This generation of ad hoc -- SQL and non-use of bind variables was resulting in proliferation of -- non-reusable code fragments in the shared pool, one user had over -- 90 shared pool segments assigned for queries that differed only by -- the selection parameter (for example "where last_name='SMITH'" -- instead of "where last_name='JONES'"). This proliferation of multiple -- nearly identical SQL statements meant that for each query issued -- the time to scan the shared pool for identical statements was increasing -- for each non-reusable statement generated. -- -- A flush of the shared pool was the only solution to solve this performance -- problem, resulting that all other query returned again in less than a second. -- -- It was determined that an automatic procedure was needed to monitor -- the shared pool and flush it when it reached 60-70% of capacity. -- -- The following procedue was created: -- CREATE OR REPLACE VIEW sys.sql_summary AS SELECT username, sharable_mem, persistent_mem, runtime_mem FROM sys.v_$sqlarea a, dba_users b WHERE a.parsing_user_id = b.user_id; CREATE OR REPLACE PROCEDURE flush_it AS CURSOR get_share IS SELECT SUM(sharable_mem) FROM sys.sql_summary; CURSOR get_var IS SELECT value FROM v$sga WHERE name like 'Var%'; CURSOR get_time is SELECT SYSDATE FROM dual; todays_date DATE; mem_ratio NUMBER; share_mem NUMBER; variable_mem NUMBER; cur INTEGER; sql_com VARCHAR2(60); row_proc NUMBER; BEGIN OPEN get_share; OPEN get_var; FETCH get_share INTO share_mem; DBMS_OUTPUT.PUT_LINE('share_mem: '||to_char(share_mem)); FETCH get_var INTO variable_mem; DBMS_OUTPUT.PUT_LINE('variable_mem: '||to_char(variable_mem)); mem_ratio:=share_mem/variable_mem; DBMS_OUTPUT.PUT_LINE('mem_ratio: '||to_char(mem_ratio)); IF (mem_ratio>0.3) THEN DBMS_OUTPUT.PUT_LINE ('Flushing Shared Pool ...'); cur:=DBMS_SQL.open_cursor; sql_com:='ALTER SYSTEM FLUSH SHARED_POOL'; DBMS_SQL.PARSE(cur,sql_com,dbms_sql.v7); row_proc:=DBMS_SQL.EXECUTE(cur); DBMS_SQL.CLOSE_CURSOR(cur); END IF; END; / -- This procedure was then loaded into the job queue and scheduled to run -- every hour using the following commands: DECLARE job NUMBER; BEGIN DBMS_JOB.SUBMIT(job,'flush_it;',sysdate,'sysdate+1/24'); END; /