The shared pool is part of the System Global Area (SGA) in Oracle databases. It contains several key memory structures including the library cache, dictionary cache, and control structures. The library cache stores parsed SQL statements and their execution plans for reuse. A shared SQL area contains the execution plan for a SQL statement that multiple users can access, while each user has their own private SQL area.
The shared pool is part of the System Global Area (SGA) in Oracle databases. It contains several key memory structures including the library cache, dictionary cache, and control structures. The library cache stores parsed SQL statements and their execution plans for reuse. A shared SQL area contains the execution plan for a SQL statement that multiple users can access, while each user has their own private SQL area.
The shared pool is part of the System Global Area (SGA) in Oracle databases. It contains several key memory structures including the library cache, dictionary cache, and control structures. The library cache stores parsed SQL statements and their execution plans for reuse. A shared SQL area contains the execution plan for a SQL statement that multiple users can access, while each user has their own private SQL area.
The shared pool is part of the System Global Area (SGA) in Oracle databases. It contains several key memory structures including the library cache, dictionary cache, and control structures. The library cache stores parsed SQL statements and their execution plans for reuse. A shared SQL area contains the execution plan for a SQL statement that multiple users can access, while each user has their own private SQL area.
POOL S QL Area PL?SQL Procedure Control Struct Object definition Latch LOCK
Tapas Kumar A shared SQL area contains the parse
Oracle DBA tree and execution plan for a single TATA CONSULTANCY SERVICES SQL statement, or for similar SQL statements. Oracle saves memory by INTRODUCTION using one shared SQL area for multiple similar DML statements, What is shared pool? This first query particularly when many users that comes, let us have a brief execute the same application. introduction regarding shared pool A shared SQL area is always in the here first. shared pool. Most of the people knows that shared pool is the part of System Global Oracle allocates memory from the Area (SGA) it’s true but little else, shared pool when a SQL statement is What exactly the shared pool? parsed; the size of this memory Shared pool are contain lots of key depends on the complexity of the memory areas of Oracle and in statement. If a SQL statement Instance tuning the major area that requires a new shared SQL area and we have to tune is shared pool if the entire shared pool has already shared pool defined improperly the been allocated, Oracle can deallocate overall database performance will items from the pool using a modified suffer. least Recently used algorithm until there is enough free space for the INTERNAL STRUCTURE – new statement's shared SQL area. A private SQL area contains data such as bind information and runtime buffers. Each session that issues a Majority shared pool related to the SQL statement has a private SQL two part of SGA one is fixed are area. Each user that submits an which is relatively constant to a identical SQL statement has his or oracle instance for a particular her own private SQL area that uses a version and the second part is single shared SQL area; many private Variable area which gradually shrink SQL areas can be associated with the and grow for user and application same shared SQL area. requirement. A private SQL area contains data Now we should do a close look of such as bind information and runtime various component of Shared Pool – buffers. Each session that issues a SQL statement has a private SQL Basically Shared Pool could be area. Each user that submits an divided in three major parts – identical SQL statement has his or 1. Library Cache her own private SQL area that uses a 2. Dictionary Cache single shared SQL area; many private 3. Control Structure SQL areas can be associated with the same shared SQL area. Library Cache – Memory Part where all the SQL and A private SQL area has a persistent area and a PL/SQL statement executed, all runtime area: execution plan reside here for SQL • The persistent area contains statement stored here. bind information that persists We can further subdivide this Library across executions, code for Chache into – datatype conversion (in case 1. Shared and Private SQL the defined datatype is not Area the same as the datatype of 2. PL/SQL Procedure Part the selected column), and other state information (like Shared and Private SQL Area – recursive or remote cursor numbers or the state of a parallel query). The size of the persistent area depends on the number of binds and PL/SQL Procedure Part – columns specified in the statement. For example, the Oracle processes PL/SQL program persistent area is larger if units (procedures, functions, many columns are specified in packages, anonymous blocks, and a query. database triggers) much the same • The runtime area contains way it processes individual SQL information used while the statements. Oracle allocates a SQL statement is being shared area to hold the parsed, executed. The size of the compiled form of a program unit. runtime area depends on the Oracle allocates a private area to type and complexity of the hold values specific to the session SQL statement being that executes the program unit, executed and on the sizes of including local, global, and package the rows that are processed variables (also known as package by the statement. In general, instantiation) and buffers for the runtime area is somewhat executing SQL. If more than one user smaller for INSERT, UPDATE executes the same program unit, and DELETE statements than then a single, shared area is used by it is for SELECT statements, all users, while each user maintains a particularly when the SELECT separate copy of his or her private statement requires a sort. SQL area, holding values specific to his or her session. Oracle creates the runtime area as the first step of an execute request. Individual SQL statements contained For INSERT, UPDATE, and DELETE within a PL/SQL program unit are statements, Oracle frees the runtime processed as described in the area after the statement has been previous sections. Despite their executed. For queries, Oracle frees origins within a PL/SQL program unit, the runtime area only after all rows these SQL statements use a shared are fetched or the query is cancelled. area to hold their parsed representations and a private area The location of a private SQL area for each session that executes the depends on the type of connection statement. established for a session. If a session (x$ksmms) table provide the is connected via a dedicated server, runtime information regarding private SQL areas are located in the PL/SQL area in Library Cache which is user's PGA. However, if a session is suppose to be allocated to a connected via the multi-threaded particular Oracle Instance – server, the persistent areas and, for E.g. – SELECT statements, the runtime select * from X$KSMSS areas, are kept in the SGA where KSMSSNAM like 'PL/SQL%' and KSMSSLEN <> 0 ;
(x$ksmms) table provide the ADDR INDX INST_ID KSMSSLEN
runtime information regarding SQL KSMSSNAM KSMDSIDX ---------------- ---------- ---------- ---------- area in Library Cache which is -------------------------- ---------- suppose to be allocated to a 000000011049B268 28 1 1501552 PL/SQL DIANA 1 particular Oracle Instance – 000000011049B268 37 1 1357968 E.g. – PL/SQL MPCODE 1
select * from X$KSMSS PL/SQL MPCODE stands for machine
where KSMSSNAM = 'sql_area' and KSMSSLEN <> 0 ; dependent pseudocode. PL/SQL DIANA stands for the PL/SQL ---------------- ---------- ---------- ---------- -------------------------- ---------- code size in the shared pool at runtime. ADDR INDX INST_ID KSMSSLEN KSMSSNAM KSMDSIDX 000000011049B268 29 1 13480352 Library Cache Manager – sql area 1 numbers are the next higher prime The main purpose of the library value. They are 251, 509, 1021, cache is to provide a mechanism to 2039, 4093, 8191, 16381, 32749, locate and store any library cache 65521, 131071, and 4292967293 object quickly. A hashing mechanism where the "n+1"th size is is used to locate a handle, which approximately twice the "n"th size. contains the identity (name) of the The resulting expansion of the hash object. The library cache handle then table will involve allocating a new points us to one or more the library hash table at the next prime size, cache objects and their contents. rehashing the library cache objects The library cache caches different from the old table to the new table, types of library objects (e.g. and freeing the space allocated from packages, procedures, functions, the old hash table. Throughout this shared cursors, anonymous procedure, access to the hash table PL/SQL blocks, table definitions, view is blocked (by freezing access to the definitions, form definitions). child Library cache memory is allocated latches) as one user allocates new out of the top most heap or the buckets to double the size of the generic SGA heap. When the library hash table and then uses the least cache, KGL, needs more memory, it significant bits of the hash value to will call the heap manager (KGH) to determine which new bucket a allocate it. The library cache consists handle belongs to. Contrary to of a hash table, which consists of an common belief, this is a rare and array of hash buckets. Each hash inexpensive operation that may bucket is a doubly linked list of cause a short (approximately 3-5 library cache object handles. Each second) hiccup in the system. The library cache object hash table never shrinks. handle points to a library cache The library cache manager will apply object and has a reference list. The a modulo hash function to a given library cache object is further broken object’s namespace, object name, down into other components such as owner, and database link to a dependency table, a child table, determine the hash bucket where the and an authorisation table (to name object should be found. It then walks a few). down the corresponding linked list to see if the object is there. If the object does not exist, the library cache manager will create an empty object with the given name, insert it in the hash table, and request the client load it by calling the client's environment-dependent load function. Basically, the client would read from disk, call the heap manager to allocate memory, and load the object. Library Cache Handle –
Library Cache Manager (Hash
Table and Hash Bucket) –
The hash table is an array of hash
buckets. The initial number of the hash buckets is 251; however, the number of buckets will increase when the number of objects in the table exceeds the next number. The next 000000011049AE88 60 1 1092352 dictionary cache 2
Control Structure -
This contain the information
regarding Internal Latch and Locks (Data Structure), it also contain buffer header, the process session A library cache handles points to a and transaction arrays. library cache object. It contains the The size of these arrays depends on name of the library object, the the setting of Initialisation parameter namespace, a timestamp, a of Init.ora file and can’t be changed reference list, a list of locks locking without shutting down the database. the object and a list of pins pinning the object. Each object is uniquely identified by the name within its namespace. The library cache manager will generate a name for every object, even anonymous PL/SQL blocks. The handle uses namespaces to partition library cache objects by types. These are examples of different types of Shared Pool Chunks – namespaces: one namespace holds all namespaces depended on PL/SQL Have close looks of Shared Pool, For objects, one for package bodies and that we should have a close look at table bodies, one for shared cursors; x$ksmsp each row in this table one for triggers; one for indexes; and shows a chunk of shared pool – one for clusters. The namespace KSMCHCOM KSMCHPTR KSMCHSIZ describes the type of an item KSMCHCLS kept in the library cache. The name ---------------- ---------------- ---------- -------- sql area 0700000005D85750 1360 consists of the object owner name, freeabl the object name, the database link 0700000005D846F8 4184 freeabl KGL handles 0700000005D84520 472 name, and the database link owner recr name. A comprehensive list can be library cache 0700000005D84478 168 viewed from v$librarycache. freeabl 0700000005D84150 808 recr A handle can be freed if there are no KQR PO 0700000005D83D20 1072 current references to it and it has not recr KGL handles 0700000005D83B48 472 been expressly marked to be kept. recr We use this to determine when a library cache 0700000005D83AA0 168 freeabl handle should be unpinned in 0700000005D83778 808 recr memory. 0700000005D83450 808 freeabl KGL handles 0700000005D83300 336
Dictionary Cache – recr
Table definition against which an When each shared pool chunk is
application user suppose to do a allocated the code is passed to a query, it include table’s associated function that does the work of Index and Columns and privilege allocation and this address is visible information regarding table as we as to KSMCHCOM column, which columns. describe the purpose of allocation. This chunk is supposed to be larger select * from X$KSMSS then the size of the object as it also where KSMSSNAM like 'PL/SQL%' and KSMSSLEN <> 0 ; contains the header information.
ADDR INDX INST_ID KSMSSLEN The column KSMCHCLS represent
KSMSSNAM KSMDSIDX ---------------- ---------- ---------- ---------- the class, there are basically four -------------------------- ---------- type of classes – Freeable – can be freed only contain reserved size, here REQUEST_MISS the objects needed for the session shows the number of times the call. request miss for a large chunk. Free – free and not contained by valid object. Recr – contain by temporary objects. SHARED_POOL SIZE Parm – contained by the permanent CALCULATION – object. The shared pool size is highly So the overall summary - application dependent. To determine the shared pool size for a production select KSMCHCOM name, system it is generally necessary to count(KSMCHCOM), sum(decode(KSMCHCLS,'recr',KSMCHSIZ)) develop the application run it on a RECREATABLE, test environment (should be enough sum(decode(KSMCHCLS,'freeabl',KSMCHSIZ)) FREEABLE like production system) get some test from result and on the basis of that x$ksmsp group by KSMCHCOM ; calculate the shared pool size. There are some few step which we should NAME COUNT(KSMCHCOM) RECREATABLE FREEABLE consider while calculating the shared ---------------- --------------- ----------- ---------- pool – PARAMETER ENTRY 4 192 PARAMETER TABLE 1 2064 PL/SQL DIANA 237 12816 479672 PL/SQL MPCODE 23 11792 50336 STORED OBJECTS – The amount of PLS cca hp desc 1 376 shared pool that needs to be PLS non-lib hp 1 2136 PRESENTATION TA 1 2064 allocated for objects that are stored SERVICE NAME EN SERVICE NAMES T 2 1 152 2064 in the database like packages and character set m 5 31936 views is character set o 4 318648 easy to measure. You can just LRU List – measure their size directly with the following statement: When a process starts it allocate select sum(sharable_mem) from some memory and when it’ fails to V$DB_OBJECT_CACHE; allocated required memory, Then it try to remove chunk containing recreatable object from SQL shared pool to get the desired size of The amount of memory needed to chunk, and removing these object store sql statements in the shared from memory is based on LRU(Least pool is more difficult to measure Recent Used) means those objects because of the needs of dynamic sql. that are frequently pinned kept in the If an application has no dynamic sql memory and those are unpinned we then the amount of memory can generally remove those objects from simply be measured after the the memory. Object those required application has run for a while by just again known as transient and other selecting it out of the shared pool as known as recurrent. follows:
ORA-04331 ‘unable to allocate x select sum(sharable_mem) from v$sqlarea;
bytes of shared pool’ when all the free memory fully exhausted If the application has a moderate or (Later we will discuss the shared large amount of dynamic sql like pool fragmentation). most applications do, then a certain amount of memory will be needed for There is one list maintained which the shared sql plus more for the known as Reserved List, it generally dynamic sql. Sufficient memory 5% of the total size of Shared Pool should be allocated so that the and reserved size is defined by dynamic sql does not age the shared SHARED_POOL_RESERVED_SIZE sql out of the shared pool. parameter in Init.ora parameter file. Approximated memory could be With the help of calculated by the following: v$shared_pool_reserved we can see select sum(sharable_mem) from v$sqlarea where executions > 5; select sum(value) all_sess_mem from v$sesstat s, v$statname n The remaining memory in v$sqlarea where s.statistic# = n.statistic# is for dynamic sql. and n.name = 'session uga memory max';
PER-USER PER-CURSOR MEMORY OVERHEAD –
– You will need to add a minimum of You will need to allow around 250 30% overhead to the values bytes of memory in the shared pool calculated above to allow for per concurrent user for each open unexpected and unmeasured usage cursor that the user of the shared pool. has whether the cursor is shared or not. During the peak usage time of Estimating Procedure (From the production system, you can Metalink) – measure this as follows: set serveroutput on;
select sum(250 * users_opening) from declare
v$sqlarea; object_mem number; shared_sql number; cursor_mem number; In a test system you can measure it mts_mem number; by selecting the number of open used_pool_size number; free_mem number; cursors for a test user and pool_size varchar2(100); multiplying by the total number of begin users: -- Stored objects (packages, views) select sum(sharable_mem) into object_mem from v$db_object_cache; select 250 * value bytes_per_user -- Shared SQL -- need to have additional from v$sesstat s, v$statname n memory if dynamic SQL used where s.statistic# = n.statistic# select sum(sharable_mem) into shared_sql from and n.name = 'opened cursors current' v$sqlarea; and s.sid = 23; -- replace 23 with session id of -- User Cursor Usage -- run this during peak user being measured usage select sum(250*users_opening) into The per-user per-cursor memory is cursor_mem from v$sqlarea; -- For a test system -- get usage for one user, one of the classes of memory that multiply by # users shows up as 'library cache' in -- select (250 * value) bytes_per_user -- from v$sesstat s, v$statname n v$sgastat. -- where s.statistic# = n.statistic# -- and n.name = 'opened cursors current' MTS – -- and s.sid = 25; -- where 25 is the sid of the process -- MTS memory needed to hold session If you are using multi-threaded information for shared server users -- This query computes a total for all currently server, then you will need to allow logged on users (run enough memory for all the shared -- during peak period). Alternatively calculate for a single user and server users to put their session -- multiply by # users. memory in the shared pool. This can select sum(value) into mts_mem from be measured for one user with the v$sesstat s, v$statname n where s.statistic#=n.statistic# following query: and n.name='session uga memory max'; select value sess_mem -- Free (unused) memory in the SGA: gives an from v$sesstat s, v$statname n indication of how much memory where s.statistic# = n.statistic# -- is being wasted out of the total allocated. and n.name = 'session uga memory' select bytes into free_mem from v$sgastat and s.sid = 23; -- replace 23 with session id of where name = 'free memory'; user being measured -- For non-MTS add up object, shared sql, A more conservative value to use is cursors and 30% overhead. used_pool_size := the maximum session memory that round(1.3*(object_mem+shared_sql+cursor_me was ever allocated by the user: m)); -- For MTS add mts contribution also. -- used_pool_size := select value sess_max_mem round(1.3*(object_mem+shared_sql+cursor_me from v$sesstat s, v$statname n m+mts_mem)); where s.statistic# = n.statistic# select value into pool_size from v$parameter and n.name = 'session uga memory max' where name='shared_pool_size'; and s.sid = 23; -- replace 23 with session id of -- Display results user being measured dbms_output.put_line ('Obj mem: '||to_char To select this value for all the (object_mem) || ' bytes'); currently logged on users the dbms_output.put_line ('Shared sql: '||to_char (shared_sql) || ' bytes'); following query can be used: dbms_output.put_line ('Cursors: '||to_char (cursor_mem) || ' bytes'); POOL_USED POOL_SIZE POOL_AVAIL POOL_PCT dbms_output.put_line ('MTS session: '||to_char ---------------- ---------------- ------- (mts_mem) || ' bytes'); 8.98988342 32 23.0101166 28.0933857 dbms_output.put_line ('Free memory: '||to_char (free_mem) || ' bytes ' || '(' || to_char(round(free_mem/1024/1024,2)) || 'M)'); If shared percentage (POOL_PCT) in dbms_output.put_line ('Shared pool utilization (total): '|| to_char(used_pool_size) || ' bytes ' || nineties then we need to increase the '(' || size of shared pool, but some time to_char(round(used_pool_size/1024/1024,2)) || 'M)'); the reason may be other of hogh Technical Reports Compendium, Volume I, 1996 percentage of shared pool. The Shared Pool Internals dbms_output.put_line ('Shared pool allocation above scripts should run periodically (actual): '|| pool_size ||' bytes ' || '(' || to get a summary of Shared Usage at to_char(round(pool_size/1024/1024,2)) || 'M)'); peak and normal time. dbms_output.put_line ('Percentage Utilized: '|| to_char (round(used_pool_size/pool_size*100)) || '%'); Now we should focus on high end; percentage usage of shared pool why it high (more then 90%). We should see whether the shared pool fill with reusable sql or with bad MONITORING & TUNING – sql, before increase the size of shared pool we should examine all Let begin with major part which is the key areas, it might be possible to knows as shared pool tuning and flush the shared pool would resolved Oracle recommend that the default the high percentage issue of shared size of Shared Pool in Init.ora pool. parameter should be ¼ of the Total So how we can see that what is in SGA in a general scenario. the shared pool? The other shared pool parameter Whether is being properly used or controls how to the variable space not. For that we can generate some area in the shared pool is parsed out. common useful report. According to the suggestion give by First report will shown here the Oracle if our total SGA size is 100 MB individual mapping of user with then we should set our Shared Pool shared pool – size 25 MB and latter increase gradually as needed by the system. Now a question comes in our mind what are the key area should be Create a temporary table to hold the monitored by the DBA to get the information related to sql area for all knowledge that the shared pool size users,that produces a summary is small. report for each user. From V$SGASTAT and V$SQLAREA we will get this information. create table temp_sql_report as (select b.username, a.SQL_TEXT, Shared Pool usage we can see at a a.execution, given point of time from the following a.load, a.user_executing script – a.SHARABLE_MEM, select a.PERSISTENT_MEM, sum(a.KSMSSLEN)/(1024*1024) Pool_used, a.RUNTIME_MEM max(c.KSPPSTVL)/(1024*1024) pool_size, from v$sqlarea a,dba_users b (max(c.KSPPSTVL)/(1024*1024))- where a.PARSING_USER_ID = b.USER_ID sum(a.KSMSSLEN)/(1024*1024)) pool_avail, (sum(a.KSMSSLEN)/max(c.KSPPSTVL))*100 SQL SUMMARY REPORT – pool_pct from x$ksmss a, x$ksppi b, x$ksppcv c REM <-- SQLAREA SUMMARY REPORT where a.KSMSSNAM in ( REM Mapping between user and sql area 'reserved stopper', usage. 'table definiti', 'dictionary cache', 'library cache', 'sql area', Col username for a20 heading USER 'PL/SQL DIANA', Col sharable_mem for a25 heading SHARABLE 'SEQ S.O.')and Col persistent_mem for a20 heading PERSIS b.indx = c.indx and Col run_time for a20 heading RUNTIME b.KSPPINM='shared_pool_size' start title80 ‘SQL AREA SUMMARY REPORT’ Spool sql_area_summary_report The out of the above script - Select The out put of the report look like Username, Sum(SHARABLE_MEM), this – Sum(PERSISTENT_MEM), Sum(RUNTIME_MEM) USERS From temp_sql_report ------------------------------ Group by username; SQL_TEXT Spool off ----------------------------------------------------------------- / ----------------------------------------------------------------- -- USERNAME SUM(SHARABLE_MEM) EXECUTIONS LOADS USERS_EXECUTING SUM(PERSISTENT_MEM) SUM(RUNTIME_MEM) SHARABLE_MEM PERSISTENT_MEM ------------------------------ ----------------- ---------- ---------- --------------- ------------ -------------- ------------------- ---------------- 0 2 0 16439 1376 SYS 3004291 237048 1097504 SYS TEST 281085 DECLARE 18040 83328 P_EQP_NO mv_tplans.eqm_eqp_no_fk%type := upper('GLDU0371682'); P_MESSAGE_NO This output of this summary report mv_edimessages.message_no%type := NULL; shows here the sql area used by each P_EQP_SIZE user. Now try to analyse the mv_tplans.eqs_eqp_size_fk%type := 20; P_EQP_TYPE summary report, if a particular hold a mv_tplans.eqt_eqp_type_code_fk%type := large amount of memory then that upper('GP '); P_REF_NO means the sql’s used by that user are mv_edimessages.ref1_no%type := bad every time it generate different upper('HAI2000229/1'); P_REF_TYPE execution plan for similar kind of mv_edimessages.ref1_type%type := B; queries, the coding produce a large P_FACILITY number of nonreusable sql area. mv_edimessages.fac_facility_fk%type := upper('SCTSOUGB'); P_EVENT_DATETM Now we can generate an another mv_edimessages.event_datetm%type := SYSDATE; P_EVENT_TYPE where we will shown the actual sql mv_eventtableitems.event_type%type := 4; statement executed by a user and P_FCL_LCL mv_tplans.fcl_lcl%type := NULL; P_BOOKING how many time a sql statement _ITEM mv_tplans.booking_item%type := 1; execute by a user , what amount of P_PLAN_ID mv_tplans.tplan_id%type ; memory that sql statement took to P_VERSION_NO mv_tplans.version_no%type; P_LEG_ID mv_tplanlegs.tleg_id%type; execute the statement. p_ack_reqd_ind number := 0; P_ACK_ERROR_CODE VARCHAR2(8); column sql_text format a60 heading Text P_BOOKING_REF_NO mv word_wrapped _tplans.booking_ref_no%type; column sharable_mem heading Shared| P_RETURN_CODE NUMBER; P_RETURN_MESG Bytes column persistent_mem heading One warning about the script, the Persistent|Bytes column loads heading Loads report it generates can run to several column users format a15 heading "User" hundred pages for a user with a large column executions number of SQL areas. What things heading "Executions" column users_executing heading should we watch for in a user's SQL "Used By" areas? First, watch for the non-use of start title132 "Users SQL Area Memory Use" spool Sql_info bind variables, bind variable usage is set long 2000 pages 59 lines 132 shown by the inclusion of variables break on users compute sum of sharable_mem on users such as ":4" in the SQL text. As the compute sum of persistent_mem on users stement using the bind variable: 4 so compute sum of runtime_mem on users is reusable. Non-bind usage means select username users, hard coded values such as upper sql_text, ('GLDU0371682') are used. Notice Executions, loads, that for most of the rest of the users_executing, statements in the report no bind sharable_mem, persistent_mem variables are used even though from many of the SQL statements are temp_sql_report nearly identical. This is one of the where b.username like upper('%&user_name%') order by 3 desc,1; leading causes of shared pool misuse spool off and results in useful SQL being drown pause Press enter to continue in tons of non-reusable garbage SQL.
The problem with non-reusable SQL
is that it must still be looked at by any new SQL inserted into the pool very expensive in both terms of CPU (actually it's hash value is scanned). used, and in the number of latch gets While a hash value scan may seem a performed. small cost item, if your shared pool contains tens of thousands of SQL Soft Parse - areas this can be a performance If session issues a SQL statement, bottleneck. which is already in the shared pool AND it, can use an existing version of As the SQL statement issued by the that statement then this is known as user is directly related to the shared a 'soft parse'. As far as the pool and using a good mechanism of application is concerned it has asked coding improve the system to parse the statement. performance and also avoid redundant parsing of PL/SQL and SQL Identical Statements? statement for Library Cache If two SQL statements mean the (memory + CPU). As Library Cache is same thing but are not identical a part of Shared pool so Indirectly we character for character then from an can say we tuned the Shared Pool. Oracle viewpoint they are different statements. Consider the following Let have a Close look of various issued by SCOTT in a single session: parsing type of SQL – SELECT ENAME from TEMP_X;
Literal SQL – A literal SQL
SELECT ename from temp_x; statement is considered as one which use literals in the predicates rather Although both of these statements then bind variable, where the value are really the same they are not of the literal is likely to differ identical as an upper case 'T' is not between various execution of the the same as a lower case 't'. statement. E.g 1 – Sharable SQL SELECT * FROM temp_x WHERE col_1='x'; If two sessions issue identical SQL is used by the application instead of statements it does NOT mean that the statement is sharable. Consider SELECT * FROM temp_x WHERE ename=:x; the following: Eg 2: SELECT sysdate FROM dual; User USER_X has a table called does not use bind variables but TEMP_X and issues: would not be considered as a literal SELECT column_x from TEMP_X; SQL statement for this article as it can be shared. Eg 3: User USER_Y has his own table called TEMP_X and also issues: SELECT vers ion FROM app_vers ion WHERE vers ion>2.0; SELECT column_y from TEMP_X; If this same statement was used for checking the 'version' throughout Although the text of the statements the application then the literal value are identical the TEMP_X tables are '2.0' is always the same so this different objects. Hence these are statement can be considered different versions of the same basic sharable. statement. There are many things that determine if two identical SQL Hard Parse - strings are truly the same statement If a new SQL statement is issued (and hence can be shared) including: which does not exist in the shared pool then this has to be parsed fully. All object names must resolve to the Eg: Oracle has to allocate memory same actual objects for the statement from the shared The optimiser goal of the sessions pool, check the statement issuing the statement should be the syntactically and semantically etc... same This is referred to as a hard parse, is The types and lengths of any bind To give a balanced picture this short variables should be "similar". (We section describes the benefits of both don’t discuss the details of this here literal SQL and sharable SQL. but different types or lengths of bind variables can cause statements to be Literal SQL classed as different versions) The NLS (National Language Support) The Cost Based Optimiser (CBO) environment which applies to the works best when it has full statistics statement must be the same and when statements use literals in their predicates. Consider the Versions of a statement following: As described in 'Sharable SQL' if two statements are textually identical but SELECT distinct cust_ref FROM orders WHERE total_cost < 10000.0; cannot be shared then these are called 'versions' of the same Versus statement. If Oracle matches to a statement with many versions it has SELECT distinct cust_ref FROM orders WHERE to check each version in turn to see if total_cost < :bindA;
it is truly identical to the statement
For the first statement the CBO could currently being parsed. Hence high use histogram statistics that have version counts are best avoided by: been gathered to decide if it would be fastest to do a full table scan of Standardising the maximum bind ORDERS or to use an index scan on lengths specified by the client TOTAL_COST (assuming there is one). Avoid using identical SQL from lots of In the second statement CBO has no different schemas, which use private idea what percentage of rows fall objects. Eg: SELECT xx FROM below ":bindA" as it has no value for MYTABLE; where each user has their this bind variable to determine an own MYTABLE execution plan . Eg: ":bindA" could be Setting 0.0 or 99999999999999999.9 _SQLEXEC_PROGRESSION_COST to '0' in Oracle 8.1 There could be orders of magnitude difference in the response time Library Cache and Shared Pool between the two execution paths so latches using the literal statement is preferable if you want CBO to work The shared pool latch is used to out the best execution plan for you. protect critical operations when This is typical of Decision Support allocating and freeing memory in the Systems where there may not be any shared pool. 'standard' statements, which are The library cache latches (and the issued repeatedly so the chance of library cache pin latch in Oracle 7.1) sharing a statement is small. Also the protect operations within the library amount of CPU spent on parsing is cache itself. typically only a small percentage of All of these latches are potential that used to execute each statement points of contention. The number of so it is probably more important to latch gets occurring is influenced give the optimiser as much directly by the amount activity in the information as possible than to shared pool, especially parse minimise parse times. operations. Anything that can minimise the number of latch gets Sharable SQL and indeed the amount of activity in the shared pool is helpful to both If an application makes use of literal performance and scalability. (unshared) SQL then this can severely limit scalability and Literal SQL versus Shared SQL throughput. The cost of parsing a new SQL statement is expensive both in terms of CPU requirements and the number of times the library cache and shared pool latches may need to sum(executions) "TotExecs" FROM v$sqlarea be acquired and released. WHERE execut ions < 5 GROUP BY substr(sql_text,1,40) HAVING count(*) > 30 Eg: Even parsing a simple SQL ORDER BY 2 ; statement may need to acquire a library cache latch 20 or 30 times. Note: If there is latch contention for the library cache latches the above The best approach to take is that all Statement may cause yet further SQL should be sharable unless it is contention problems. adhoc or infrequently used SQL The values 40,5 and 30 are example where it is important to give CBO as values so this query is looking for much information as possible in order different statements whose first 40 for it to produce a good execution characters are the same which have plan. only been executed a few times each and there are at least 30 different Reducing the load on the Shared Pool occurrences in the shared pool. This query uses the idea it is common for Parse Once / Execute Many literal statements to begin "SELECT col1, col2, col3 FROM table By far the best approach to use in WHERE..." with the leading portion of OLTP type applications is to parse a each statement being the same. statement only once and hold the Note: There is often some degree of cursor open, executing it as required. resistance to converting literal SQL to This results in only the initial parse use bind variables. Be assured that it for each statement (either soft or has been proven time and time again hard). Obviously there will be some that performing this conversion for statements which are rarely the most frequently occurring executed and so maintaining an open statements can eliminate problems cursor for them is a wasteful with the shared pool and improve overhead. scalability greatly.
Note that a session only has
<Parameter: OPEN_CURSORS> Performance Effects cursors available and holding cursors open is likely to increase the total Oracle performance can be severely number of concurrently open cursors. compromised by large volumes of literal SQL. Some of the symptoms In precompilers the HOLD_CURSOR that may be noticed are: parameter controls whether cursors are held open or not while in OCI • System is CPU bound and exhibits developers have direct control over an insatiable appetite for CPU. cursors. • System appears to periodically “hang” after some period of Eliminating Literal SQL normal operation. • Latch contention on shared pool If you have an existing application it and library cache latches. is unlikely that you could eliminate all literal SQL but you should be • Increasing the shared pool size prepared to eliminate some if it is delays the problem but it re- causing problems. By looking at the occurs more severely. V$SQLAREA view it is possible to see Identifying the Problem which literal statements are good candidates for converting to use bind An Oracle instance suffering from too variables. The following query that much literal SQL will likely exhibit shows SQL in the SGA where there some of the symptoms above. There are a large number of similar are several investigations the DBA statements: can use to help confirm that this is indeed happening in the instance. SELECT substr (sq l _ text ,1 ,40) "SQL" , count(*) , Library Cache Hit Ratio When this query selects more than 5- 10% of total sessions there is likely The library cache hit ratio should be very serious performance very high (98%) when SQL is being degradation taking place and literal shared and will remain low regardless SQL may be the culprit. of shared pool sizing adjustments when SQL is chronically non- Finding Literal SQL sharable. Use the following query to We can attempt to locate literal SQL determine the hit ratios by in the V$SQL fixed view by grouping namespace in the library cache. and counting statements that are identical up to a certain point based SELECT namespace on the observation that most literal ,(100*gethitratio ) hit_ratio FROM v$librarycache; SQL becomes textually distinct toward the end of the statement (e.g. in the WHERE clause). The following The “SQL AREA” namespace will be query returns SQL statements having the one affected by literal SQL. more than 10 statements that SQL Parse-to- Execute Ratio textually match on leading substring.
The following query displays the
SELECT S.sql_text percentage of SQL executed that did FROM v$sql S not incur an expensive hard parse. ,(select substr(sql_text,1,&&size) sqltext Literal SQL will always be fully ,count(*) parsed, so a low percentage may from v$sql group by indicate a literal SQL or other SQL substr(sql_text,1,&&size) sharing problem. hav ing count(* ) > 10 ) D WHERE substr(S.sql_text,1,&&size) = SELECT 100 * (1 - D.sqltext; A.hard_parses/B.executions) noparse_ratio FROM The SQL*Plus substitution variable (select value hard_parses &&size can be adjusted to vary the from v$sysstat where name = 'parse count text length used to match (hard)' ) A statements, as can the value 10 used ,(select value executions from v$sysstat to filter by level of duplication. Note where name = 'execute count' ) that this query is expensive and B; should not be executed frequently on production systems. Again, when this ratio is high Oracle is sparing CPU cycles by avoiding MEMORY FRAGMENTATION – expensive parsing and when low there may be a literal SQL problem. The primary problem that occurs is that free memory in the shared pool Latch Free Waiters becomes fragmented into small A telltale sign that the instance is pieces over time. suffering library cache and shared Any attempt to allocate a large piece pool problems is active latch of memory in the shared pool will contention with sessions waiting on cause large amount of objects in the the “latch free” wait event. The library cache to be flushed out and following query will select all current may result in an ORA-4031 out of sessions waiting for either the shared shared memory error. pool or library cache latches. DIAGNOSIS i) ORA-4031 ERROR SELECT sid, event, name latch FROM v$session_wait w One way to diagnose that this is ,v$latch l happening is to look for ORA-4031 WHERE w.event = 'latch free' AND l.latch# = w.p2 errors being returned from AND l.name IN (‘shared applications. When an attempt is pool’,’library cache’); made to allocate a large contiguous piece of shared memory, and not enough contiguous memory can be There is a fixed table called created in the shared pool, the X$KSMLRU that tracks allocations in database will signal this error. the shared pool that cause other Before this error is signalled, all objects in the shared pool to be aged objects in the shared pool that are out. This fixed table can be used to not currently pinned or in use will be identify what is causing the large flushed from the shared pool, and allocation. The columns of this their memory will be freed and fixed table are the following: merged. This error only occurs when KSMLRCOM - allocation comment there is still not a large enough that describes the type of allocation. contiguous piece of free memory If this comment is something like after this happens. There may be 'MPCODE' or 'PLSQL%' then there is a very large amounts of total free large PL/SQL object being loaded into memory in the shared pool, but just the shared pool. This PL/SQL object not enough contiguous memory. will need to be 'kept' in the shared Note: The compiled code for a pool. package was split into more than If this comment is 'kgltbtab' then the one-piece, each piece being only allocation is for a dependency table about 12K in size. So, the 64K in the library cache. This is only a restriction was lifted; however, problem when several hundred users packages larger 100K still may have are logged on using distinct user ids. problems compiling. Furthermore, The solution in this case is to use with releases 7.2/2.3 of fully qualified names for all table Oracle7/PLSQL, loading a library unit references. This problem will not (package, function, and procedure) occur in 7.1.3 or later. into the shared pool does NOT If you are running MTS and the require one contiguous piece of comment is something like 'Fixed memory in the shared pool. This UGA' then the problem is that the means that chances of getting ORA- init.ora parameter 4031 is dramatically reduced. 'open_cursors' is set too high. ii) INIT.ORA PARAMETER KSMLRSIZ - amount of contiguous An init.ora parameter can be set so memory being allocated. Values over that whenever an ORA-4031 error is around 5K start to be a problem, signalled a dump will occur into a values over 10K are a serious trace file. By looking for these trace problem, and values over 20K are files, the DBA can determine that very serious problems. Anything less these errors are occurring. This is then 5K should not be a problem. useful when applications do not KSMLRNUM - number of objects that always report errors signalled by were flushed from the shared pool in oracle, or if users do not report the order allocate the memory. errors to the DBAs. The parameter is KSMLRHON - The name of the object the following: being loaded into the shared pool if Event = "4031 trace name the object is a PL/SQL object or a errorstack" cursor. This will cause a dump of the oracle KSMLROHV - hash value of object state objects to occur when this error being loaded is signalled. By looking in the dump KSMLRSES - SADDR of the session for that loaded the object. 'Load=X' and then looking up a few The advantage of X$KSMLRU is that lines for 'name=' you can often tell it allows you to identify problems whether an object was being loaded with fragmentation that are effecting into the shared pool when this error performance, occurred. If an object was being but that are not bad enough to be loaded then it is likely that this load causing ORA-4031 errors to be is the cause of the problem and the signalled. If a lot of objects are being Object should be 'kept' in the shared periodically flushed from the shared pool. The object being loaded is the pool then this will cause response object printed after the 'name='. time problems and will likely cause iii) X$KSMLRU library cache latch contention Problems when the objects are blocks, then these will need to be put reloaded into the shared pool. into packages and marked kept. One unusual thing about the You can determine what large stored X$KSMLRU fixed table is that the objects are in the shared pool by contents of the fixed table are erased selecting from the whenever someone selects from the V$DB_OBJECT_CACHE fixed view. This fixed table. This is done since the will also tell you which objects have fixed table stores only the largest been marked kept. This can be done allocations that have occurred. The with the following query: values are reset after being selected select * from V$DB_OBJECT_CACHE so that subsequent large allocations where sharable_mem > 10000; can be noted even if they were not Note that this query will not catch quite as large as others that occurred PL/SQL objects that are only rarely previously. Because of this resetting, used and therefore the PL/SQL object the output of selecting from this is not currently table should be carefully noted loaded in the shared pool. Since it cannot be reselected if it is To determine what large PL/SQL forgotten. Also you should take care objects are currently loaded in the that there are not multiple people on shared pool, are not marked ‘kept’, one database that select from this and therefore may cause a problem, table because only one of them will execute the following: select the real data. Technical Reports Compendium, select name, sharable_mem from V$DB_OBJECT_CACHE Volume I, 1996 Shared Pool Internals where sharable_mem > 10000 To monitor this fixed table just runs and (type = 'PACKAGE' or type = 'PACKAGE BODY' or type = 'FUNCTION' the following: or type = 'PROCEDURE') and kept = 'NO'; select * from X$KSMLRU where KSMLRSIZ > 5000; ii) USE BIND VARIABLES Another thing that can be done to ACTION reduce the amount of fragmentation i) KEEPING OBJECTS is to reduce or eliminate the number The primary source of problems is of SQL statements in the shared pool large PL/SQL objects. The means of that are duplicates of each other correcting these errors is to 'keep” except for a constant that is large PL/SQL objects in the shared embedded in the statement. The pool at startup time. This will load statements should be replaced with the objects into the shared pool and one statement that uses a bind will make sure that the objects are variable instead of a constant. never aged out of the shared pool. If For example: the objects are never aged out then select * from emp where empno=1; there will not be a problem with select * from emp where empno=2; select * from emp where empno=3; trying to load them and not having enough memory. Should all be replaced with: select * from emp where empno=:1; Objects are 'kept' in the shared pool You can identify statements that using the dbms_shared_pool package potentially fall into this class with a that is defined in the dbmspool.sql query like the following: file. For example: select substr(sql_text, 1, 30) sql, count(*) copies from v$sqlarea exec dbms_shared_pool.keep('SYS.STANDARD'); group by substr(sql_text, 1, 30) having count(*) > 3; All large packages that are shipped iii) MAX BIND SIZE should be 'kept' if the customer uses It is possible for a sql statement to PL/SQL. This includes 'STANDARD', not be shared because the max bind 'DBMS_STANDARD', and 'DIUTIL'. variable lengths of the bind variables All large customer packages should in the statement also be marked 'kept'. do not match. This is automatically One restriction on the 'keep' taken care of for precompiler procedure is that it only works on programs and forms programs, but packages. If the customer has large could be a problem for programs that procedures or large anonymous directly use OCI. The bind call in OCI takes two arguments, one is the max open anon; loop length of the value, and the other is fetch anon into addr, hash; a pointer to the actual length. If the exit when anon%notfound; dbms_shared_pool.keep(addr || ',' || current length is always passed in as to_char(hash), 'C'); the max length instead of the max end loop; end; possible length for the variable, then this could cause the sql statement not to be shared. To identify statements that might Initialization Parameters potentially have this problem execute the following statement: The following Oracle initialization select sql_text, version_count from v$sqlarea parameters have an important where version_count > 5; impact on library cache and shared iv) ELIMINATING LARGE ANONYMOUS pool performance. PL/SQL Large anonymous PL/SQL blocks _KGL_BUCKET_COUNT should be turned into small _KGL_LATCH_COUNT anonymous PL/SQL blocks that call packaged functions. The cursor_sharing packages should be 'kept' in memory. shared_pool_size This includes anonymous PL/SQL shared_pool_reserved_size blocks that are used for trigger definitions. Large anonymous blocks shared_pool_reserved_min_all can be identified with the following oc query: large_pool_size select sql_text from v$sqlarea where command_type=47 -- command type for large_pool_min_alloc anonymous block and length(sql_text) > 500; parallel_min_message_pool Note that this query will not catch backup_io_slaves PL/SQL blocks that are only rarely temporary_table_locks used and therefore the PL/SQL block is not currently loaded in the shared dml_locks pool. sequence_cache_entries Another option that can be used row_cache_cursors when an anonymous block cannot be turned into a package is to mark the max_enabled_roles anonymous block with some string so mts_dispatchers that it can be identified in mts_max_dispatchers v$sqlarea and marked 'kept'. For example, instead of using mts_servers declare x number; begin x := 5; end; mts_max_servers one can use: declare /* KEEP_ME */ x number; begin x := 5; cursor_space_for_time end;
You can then use the following SUMMARY –
procedure to select these statements out of the shared pool and mark Here I try to provide some general them 'kept' using the information regarding shared pool dbms_shared_pool.keep package. and some internal information declare regarding memory structure, I hope /* DONT_KEEP_ME */ this information will useful for DBA’s, addr varchar2(10); I also try to provide some information hash number; cursor anon is related to application user relation to select address, hash_value application point of views. from v$sqlarea where command_type = 47 -- command type for anonymous block References and sql_text like '% KEEP_ME %' and sql_text not like '%DONT_KEEP_ME%'; 1. "Oracle Internals" Stev Adams begin 2. Metalink.oracle.com 3. Quest pipeline.