<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Real Life Database / SQL Experiences : An Oracle Blog from Vivek Sharma</title>
	<atom:link href="http://viveklsharma.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://viveklsharma.wordpress.com</link>
	<description>Being an Oracle Professional, I like to share all my Real Life Performance Tuning Challenges and Experiences.  The Content and Views on this site are my own and not necessarily those of Oracle. While, I write on my real life experiences, the resolutions mentioned are solely mine. Comments / Criticisms are always a welcome.</description>
	<lastBuildDate>Sat, 28 Jan 2012 16:03:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='viveklsharma.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Real Life Database / SQL Experiences : An Oracle Blog from Vivek Sharma</title>
		<link>http://viveklsharma.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://viveklsharma.wordpress.com/osd.xml" title="Real Life Database / SQL Experiences : An Oracle Blog from Vivek Sharma" />
	<atom:link rel='hub' href='http://viveklsharma.wordpress.com/?pushpress=hub'/>
		<item>
		<title>SQL*Plus Connection Slow ! Library Cache Lock&#8230;..</title>
		<link>http://viveklsharma.wordpress.com/2012/01/27/sqlplus-connection-slow-library-cache-lock/</link>
		<comments>http://viveklsharma.wordpress.com/2012/01/27/sqlplus-connection-slow-library-cache-lock/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 09:24:38 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[Library Cache]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[28401]]></category>
		<category><![CDATA[invalid password]]></category>
		<category><![CDATA[library cache lock]]></category>
		<category><![CDATA[row cache lock]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=482</guid>
		<description><![CDATA[Oracle Database 11g introduced a new security feature, which is meant to protect a users&#8217; password. Refer to section &#8220;What are the Oracle Password built-in Password Protections ?&#8221; of Chapter 3 of Oracle Database Security Guide. The document says, if a user tries to log in to the database more than 3 times with an [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=482&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Oracle Database 11g introduced a new security feature, which is meant to protect a users&#8217; password. Refer to section <b>&#8220;What are the Oracle Password built-in Password Protections ?&#8221;</b> of Chapter 3 of Oracle Database Security Guide. The document says, if a user tries to log in to the database more than 3 times with an Invalid Password, Oracle Database delays each login after third try. Most of them are unware of this new Security feature, and therefore, this sometimes creates a panic situation and an unexpected escalations to Oracle Support.</p>
<p align="justify">Recently, one of my customer reported a slow database connection to one of their Application Schema. The connections to other schemas, except the problematic one, were going through perfectly fine. The application connects to the Database through Weblogic Server and the problem summary mentioned that while the Weblogic Server is able to connect successfully (with zero delay) to the same schema on UAT, it takes around 30 seconds to connect to the same user on production. Therefore, concern over an issue with Database Server was raised. A severity 1 SR was raised and operating system truss output for the problematic and non-problematic user was uploaded as well. The code path of both the output was exactly same, except for the time taken for the problematic user.</p>
<p align="justify">One simple logic to understand was, that if it is an Oracle Server Issue, then it should cause the delay in connection for all the Schema&#8217;s and not just to one. Therefore, there had to be some problem with this Schema. It was thoroughly checked whether there are any AUDITING or ON-LOGON Triggers on this Schema. Database Audit Trail was enabled for all the users and therefore, this was not an exception for this schema. There were no ON-LOGON triggers on this User. Therefore, what was causing this delay was a big question.</p>
<p align="justify">Customer noticed this due to the fact that they have couple of scheduled cron jobs that runs every 30 seconds. These jobs usually takes, 5-10 seconds to complete, but since last few days, they have observed these overlapping. While Investigating this issue, I noticed that when we issue sqlplus username/password, the session waits on Library Cache Lock for around 15-20 seconds and then authenticates the user. This was the case with the scheduled jobs as well. Each of these jobs were waiting on the latch. Why should an SQL*Plus command wait on Library Cache Lock ? For other users, it could immediately authenticate.</p>
<p align="justify">In this case, Database Audit Trail, which inserts a record in aud$ came to our rescue. In the aud$ table, we noticed that for last 3-4 days, the number of failed attempts had increased dramatically. Further, it was also revealed that these connections from our the Application Servers configured at a DR site and were pointing to the production database server using wrong password. The error message reported in the aud$ was 1017, which is &#8220;Invalid Username / Password&#8221;.</p>
<p align="justify">The library cache lock wait is seen due to the fact that the account status gets updated due to incorrect login and is maintained in the library cache. This is to prevent password guessing attack as there&#8217;s a sleep in the code when incorrect login attempts exceed count of 3. These sleeps cause the latch, as the process holding it is yet to release the lock. While this behaviour is a Security enhancements, it can be disabled by setting event 28401.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/482/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=482&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2012/01/27/sqlplus-connection-slow-library-cache-lock/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>India Localization ! R12 Upgrade Performance Issues&#8230;..</title>
		<link>http://viveklsharma.wordpress.com/2012/01/03/india-localization-r12-upgrade-performance-issues/</link>
		<comments>http://viveklsharma.wordpress.com/2012/01/03/india-localization-r12-upgrade-performance-issues/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 17:28:29 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[Optimizer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[India Localization]]></category>
		<category><![CDATA[Matched Receipt Application]]></category>
		<category><![CDATA[R12 Upgrade]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=473</guid>
		<description><![CDATA[First, let me wish my readers a very Happy &#38; Prosperous New Year. While the heading of this blog relates to India Localization and Performance Issues post R12 Upgrade, the solution that I talk about actually translates to Effective Query Writing. One of my customer is in a final phase of Apps R12 Upgrade and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=473&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">First, let me wish my readers a very Happy &amp; Prosperous New Year.</p>
<p align="justify">While the heading of this blog relates to India Localization and Performance Issues post R12 Upgrade, the solution that I talk about actually translates to Effective Query Writing. One of my customer is in a final phase of Apps R12 Upgrade and is facing some slowness in a Test Environment. While I am working on all of these, I thought of writing on One Issue at a time, as and when, these are resolved. The database is 11gR2. Slowness in Matched Receipt Application was reported and an 10046 Trace file was sent to me for analysis. From the trace file, I could see 2 Queries that were consuming most of the CPU time and resolving these would bring down the execution time. The Queries are mentioned below :</p>
<pre>
SELECT wda.delivery_id, count(wda.delivery_detail_id) delivery_detail_count
FROM	wsh_new_deliveries wnd,
	wsh_delivery_assignments wda,
	wsh_delivery_details wdd,
	jai_om_oe_so_lines jsl
WHERE 	wnd.status_code NOT IN ( 'CO', 'CL', 'IT')
AND 	wnd.organization_id = :1
AND 	wda.delivery_id = wnd.delivery_id
AND  	wdd.delivery_detail_id = wda.delivery_detail_id
AND 	wdd.source_code = 'OE'
AND 	wdd.organization_id = :2
AND 	wdd.source_header_id = jsl.header_id
AND  	wdd.source_line_id = jsl.line_id
AND 	((:3 = 'UN MATCH'
AND 	EXISTS (select ref_line_id
		from 	JAI_CMN_MATCH_RECEIPTS
		where 	ref_line_id = wda.delivery_detail_id
		AND 	order_invoice ='O'
		and 	ship_status IS NULL) ) OR
  	(:4 = 'MATCH'
  	AND NOT EXISTS (select ref_line_id
  			from 	JAI_CMN_MATCH_RECEIPTS
  			where 	ref_line_id = wda.delivery_detail_id
  			AND  	order_invoice ='O'
  			and 	ship_status IS NULL) ) )
  AND 	wdd.customer_id = nvl(:5, wdd.customer_id )
  AND 	wdd.source_header_id = nvl(:6,wdd.source_header_id )
  GROUP BY wda.delivery_id ;

SELECT ott.name, ott.transaction_type_id
FROM 	oe_transaction_types_tl ott,
	oe_order_headers_all oh,
	oe_order_lines_all ol,
  	jai_om_oe_so_lines jsl
WHERE 	(NAME LIKE :b1)
AND 	( ott.transaction_type_id = oh.order_type_id
AND 	oh.header_id = ol.header_id
AND 	ol.header_id = jsl.header_id
AND 	ol.line_id = jsl.line_id
AND 	ol.ship_from_org_id = :2
AND	ol.sold_to_org_id = nvl(:3, ol.sold_to_org_id ) )
GROUP BY ott.name, ott.transaction_type_id
</pre>
<p align="justify">Since the solution for both the Queries are same, to make this smaller, a detailed explanation on Query 1 wll dominate the blog. The Execution Plan of Query 1 is pasted below and the problematic part is marked as bold (and arrow marked, in case, some browser does not display characters in BOLD). I have also mentioned the run time values of the Bind Variables from v$sql_bind_capture. These values usually help to run the query from SQL*Plus and validate the working of a query.</p>
<pre>
Bind Capture Value
------------------
SQL_ID        CHILD_ADDRESS    NAME         POSITION DATATYPE_STRING      VALUE_STRING
------------- ---------------- ---------- ---------- -------------------- --------------------
byzqm6cf3j226 07000009D7614120 :1                  1 NUMBER               52
byzqm6cf3j226 07000009D7614120 :2                  2 NUMBER               52
byzqm6cf3j226 07000009D7614120 :3                  3 CHAR(32)             MATCH
byzqm6cf3j226 07000009D7614120 :4                  4 CHAR(32)             MATCH
byzqm6cf3j226 07000009D7614120 :5                  5 CHAR(32)             NULL
byzqm6cf3j226 07000009D7614120 :6                  6 NUMBER               NULL

Plan hash value: 2965431451

------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |                             |       |       | 64721 (100)|          |
|   1 |  SORT GROUP BY                     |                             |     1 |    67 |            |          |
|   2 |   CONCATENATION                    |                             |       |       |            |          |
|*  3 |    FILTER                          |                             |       |       |            |          |
|*  4 |     FILTER                         |                             |       |       |            |          |
|   5 |      NESTED LOOPS                  |                             |     1 |    67 | 64704  (61)| 00:00:01 |
|   6 |       NESTED LOOPS                 |                             |     1 |    55 | 64704  (61)| 00:00:01 |
|   7 |        NESTED LOOPS                |                             |     7 |   294 | 64691  (61)| 00:00:01 |
<b>|*  8 |         TABLE ACCESS BY INDEX ROWID| WSH_DELIVERY_DETAILS        |     7 |   217 | 64677  (61)| 00:00:01 |&lt;--------
|*  9 |          INDEX RANGE SCAN          | WSH_DELIVERY_DETAILS_TI6    |   142K|       |  4194  (91)| 00:00:01 |&lt;--------</b>
|* 10 |         TABLE ACCESS BY INDEX ROWID| WSH_DELIVERY_ASSIGNMENTS    |     1 |    11 |     2  (50)| 00:00:01 |
|* 11 |          INDEX RANGE SCAN          | WSH_DELIVERY_ASSIGNMENTS_N3 |     1 |       |     0   (0)|          |
|* 12 |        INDEX RANGE SCAN            | WSH_NEW_DELIVERIES_TI1      |     1 |    13 |     2  (50)| 00:00:01 |
|* 13 |       INDEX RANGE SCAN             | JAI_OM_OE_SO_LINES_N1       |     1 |    12 |     0   (0)|          |
|* 14 |     TABLE ACCESS BY INDEX ROWID    | JAI_CMN_MATCH_RECEIPTS      |     1 |    15 |     8  (50)| 00:00:01 |
|* 15 |      INDEX RANGE SCAN              | JAI_CMN_MATCH_RECEIPTS_N1   |     1 |       |     6  (50)| 00:00:01 |
|* 16 |     TABLE ACCESS BY INDEX ROWID    | JAI_CMN_MATCH_RECEIPTS      |     1 |    15 |     8  (50)| 00:00:01 |
|* 17 |      INDEX RANGE SCAN              | JAI_CMN_MATCH_RECEIPTS_N1   |     1 |       |     6  (50)| 00:00:01 |
|* 18 |    FILTER                          |                             |       |       |            |          |
|* 19 |     FILTER                         |                             |       |       |            |          |
|  20 |      NESTED LOOPS                  |                             |     1 |    67 |    16  (50)| 00:00:01 |
|  21 |       NESTED LOOPS                 |                             |     1 |    54 |    14  (50)| 00:00:01 |
|  22 |        NESTED LOOPS                |                             |     1 |    43 |    12  (50)| 00:00:01 |
|* 23 |         TABLE ACCESS BY INDEX ROWID| WSH_DELIVERY_DETAILS        |     1 |    31 |    12  (50)| 00:00:01 |
|* 24 |          INDEX RANGE SCAN          | WSH_DELIVERY_DETAILS_N2     |     9 |       |     6  (50)| 00:00:01 |
|* 25 |         INDEX RANGE SCAN           | JAI_OM_OE_SO_LINES_N1       |     1 |    12 |     0   (0)|          |
|* 26 |        TABLE ACCESS BY INDEX ROWID | WSH_DELIVERY_ASSIGNMENTS    |     1 |    11 |     2  (50)| 00:00:01 |
|* 27 |         INDEX RANGE SCAN           | WSH_DELIVERY_ASSIGNMENTS_N3 |     1 |       |     0   (0)|          |
|* 28 |       INDEX RANGE SCAN             | WSH_NEW_DELIVERIES_TI1      |     1 |    13 |     2  (50)| 00:00:01 |
|* 29 |     TABLE ACCESS BY INDEX ROWID    | JAI_CMN_MATCH_RECEIPTS      |     1 |    15 |     8  (50)| 00:00:01 |
|* 30 |      INDEX RANGE SCAN              | JAI_CMN_MATCH_RECEIPTS_N1   |     1 |       |     6  (50)| 00:00:01 |
|* 31 |     TABLE ACCESS BY INDEX ROWID    | JAI_CMN_MATCH_RECEIPTS      |     1 |    15 |     8  (50)| 00:00:01 |
|* 32 |      INDEX RANGE SCAN              | JAI_CMN_MATCH_RECEIPTS_N1   |     1 |       |     6  (50)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(((:B4='UN MATCH' AND  IS NOT NULL) OR (:B3='MATCH' AND  IS NULL)))
   4 - filter(:B1 IS NULL)
   8 - filter(("WDD"."SOURCE_CODE"='OE' AND "WDD"."SOURCE_HEADER_ID" IS NOT NULL AND
              "WDD"."CUSTOMER_ID"=NVL(:B2,"WDD"."CUSTOMER_ID")))
   9 - access("WDD"."ORGANIZATION_ID"=:B5)
  10 - filter("WDA"."DELIVERY_ID" IS NOT NULL)
  11 - access("WDD"."DELIVERY_DETAIL_ID"="WDA"."DELIVERY_DETAIL_ID")
  12 - access("WND"."ORGANIZATION_ID"=:B6 AND "WDA"."DELIVERY_ID"="WND"."DELIVERY_ID")
       filter(("WND"."STATUS_CODE"'IT' AND "WND"."STATUS_CODE"'CL' AND "WND"."STATUS_CODE"'CO'))
  13 - access("WDD"."SOURCE_LINE_ID"="JSL"."LINE_ID" AND "WDD"."SOURCE_HEADER_ID"="JSL"."HEADER_ID")
  14 - filter(("SHIP_STATUS" IS NULL AND "ORDER_INVOICE"='O'))
  15 - access("REF_LINE_ID"=:B1)
  16 - filter(("SHIP_STATUS" IS NULL AND "ORDER_INVOICE"='O'))
  17 - access("REF_LINE_ID"=:B1)
  18 - filter(((:B4='UN MATCH' AND  IS NOT NULL) OR (:B3='MATCH' AND  IS NULL)))
  19 - filter(:B1 IS NOT NULL)
  23 - filter(("WDD"."ORGANIZATION_ID"=:B5 AND "WDD"."SOURCE_CODE"='OE' AND
              "WDD"."CUSTOMER_ID"=NVL(:B2,"WDD"."CUSTOMER_ID")))
  24 - access("WDD"."SOURCE_HEADER_ID"=:B1)
  25 - access("WDD"."SOURCE_LINE_ID"="JSL"."LINE_ID" AND "WDD"."SOURCE_HEADER_ID"="JSL"."HEADER_ID")
  26 - filter("WDA"."DELIVERY_ID" IS NOT NULL)
  27 - access("WDD"."DELIVERY_DETAIL_ID"="WDA"."DELIVERY_DETAIL_ID")
  28 - access("WND"."ORGANIZATION_ID"=:B6 AND "WDA"."DELIVERY_ID"="WND"."DELIVERY_ID")
       filter(("WND"."STATUS_CODE"'IT' AND "WND"."STATUS_CODE"'CL' AND "WND"."STATUS_CODE"'CO'))
  29 - filter(("SHIP_STATUS" IS NULL AND "ORDER_INVOICE"='O'))
  30 - access("REF_LINE_ID"=:B1)
  31 - filter(("SHIP_STATUS" IS NULL AND "ORDER_INVOICE"='O'))
  32 - access("REF_LINE_ID"=:B1)
</pre>
<p align="justify">WSH_DELIVERY_DETAIL is the diriving Table, which is scanned via an Index on ORGANIZATION_ID (Index WSH_DELIVERY_DETAILS_T16). See Step 9 from the Predicate Information Section. </p>
<p></u><b>Analysis</b></u></p>
<p align="justify">The Logical Reads of this query is around 0.23 Million per Execution. For Analysis, it was important to validate whether the Driving Table and Access Path chosen by the optimizer is Optimal. Therefore, I first targetted Step 8 &amp; 9 of the Execution plan, which is the driving step. Step 9 says an Index Scan and the estimated rows from this step is around 142k. This means, after scanning and filtering the data for an Organization_ID, the optimizer estimates around 142k rows will be returned and passed to the next step, which is to visit the table to filter additional non-indexed predicates. From Step 8, it can be seen that these non-indexed predicates are SOURCE_CODE, CUSTOMER_ID and SOURCE_HEADER_ID. Once the non-indexed predicates are applied, the optimizer estimates 7 rows to be returned by the final step 8. Based on this, the next action, which is to come out with a Optimal Access Path. In this case, it is a Nested Loop Join. Only 7 rows out of 142K seemed to be a problem and therefore, the next step was to validate the optimizer calculation. Following table shows the Statistics that Optimizer takes into consideration and next we shall manually run the formula to check the calculation.</p>
<pre>
## Number of Rows in the Table

SQL&gt; @table_stats
Enter value for 1: WSH_DELIVERY_DETAILS
old   2: where table_name=upper('&amp;1')
new   2: where table_name=upper('WSH_DELIVERY_DETAILS')

OWNER                          PAR   NUM_ROWS     BLOCKS LAST_ANAL GLO DEGREE
------------------------------ --- ---------- ---------- --------- --- ----------
WSH                            NO    11148400     673435 14-DEC-11 YES          1

## Column Statistics (Only relevant columns specified in the Query are displayed)

SQL&gt; @column_stats
Enter value for 1: WSH
old   3: where owner='&amp;1'
new   3: where owner='WSH'
Enter value for 2: WSH_DELIVERY_DETAILS
old   4: and   table_name='&amp;2'
new   4: and   table_name='WSH_DELIVERY_DETAILS'

COLUMN_NAME                    NUM_DISTINCT  NUM_NULLS    DENSITY HISTOGRAM
------------------------------ ------------ ---------- ---------- ---------------
CUSTOMER_ID                            9250      31395 .000108108 NONE
ORGANIZATION_ID                          78          0 .012820513 NONE
SOURCE_CODE                               2          0         .5 NONE
SOURCE_HEADER_ID                    1171510    1090944 8.5360E-07 NONE
</pre>
<p align="justify">The table has around 11 Million Rows. The Optimizer Calculation for Number of Rows expected from Index Scan is = 11148400*1/78 (Num_Distinct of Organization_Id) = 142928.905 = 142k. This matches the calculation. Step 8 is a filter from non-indexed columns used in the WHERE clause. Therefore, it is 142928*1/9250*1/2 = 7.72 = 7 (9250 for Customer_id and 2 for Source_code). Optimizer, in this case, has not considered source_header_id in the computation, as this column is also used in the JOIN Predicate, else the expected rows would have gone down further. This miscalculation of 7 Rows is enough to generate a wrong execution plan, particularly if the values against the bind variables :5 and :6 is NULL. Again, let us revisit the WHERE predicate of the query that FILTERS a condition on Customer_id &amp; Source_code.</p>
<pre>

AND 	wdd.source_code = 'OE'  &lt;-- Non Indexed Column
AND 	wdd.organization_id = :2 &lt;--- Indexed Column (Bind Value passed as 52)
  AND 	wdd.customer_id = nvl(:5, wdd.customer_id ) &lt;--- Non Indexed Column (Bind Value passed as NULL)
</pre>
<p align="justify">As mentioned in my previous paragraph, the NULL values means a a condition wdd.customer_id = wdd.customer_id, but Optimizer takes this predicate into calculation and therefore, misbehaves. While better indexing strategy or more detailed statistics would help Optimizer calculate nearly accurate cardinality, this can have an impact on other queries as well. Therefore, a better strategy would be to write the query, as per best practices, which would generate an Optimal Execution Plan.</p>
<p align="justify">The change would be, since the values for :5 &amp; :6, which is for customer_id and source_header_id respectively, is passed as NULL, these predicates are unwanted in the query. When the Query was executed, with these 2 columns removed, the execution time and the I/O’s reduced. However, we cannot always assume that these will be NULL and therefore, the query needs to be written based on the runtime choice. In this case, since there are 2 columns, which could be either NULL or NOT NULL, there would be 4 Combinations by way of which this query can be written. These Combination will be :&gt;/p&gt;</p>
<pre>
   1. Customer_ID is NULL and Source_header_id is NULL
   2. Customer_id is NULL and Source_header_id is NOT NULL
   3. Customer_Id is NOT NULL and Source_header_id is NULL
   4. Customer_Id is NOT NULL and Source_header_id is NOT NULL
</pre>
<p align="justify">Since the choice is between 2 values (NULL &amp; NOT NULL), the number of permutation and combination would depend on the number of columns. In this case, 2^2 = 4. If there are 3 columns, it will be 2^3=8. Following table shows the change in the WHERE clause to accommodate the 4 Combinations mentioned above.</p>
<pre>
## MODIFICATION 1 both customer_id and source_header_id is null

SELECT /*+ MODIFICATION 1 REMOVED BOTH NULL COLUMNS */ wda.delivery_id, count(wda.delivery_detail_id) delivery_detail_count
		FROM	wsh_new_deliveries wnd,
		wsh_delivery_assignments wda,
		wsh_delivery_details wdd,
		jai_om_oe_so_lines jsl
	WHERE 	wnd.status_code NOT IN ( 'CO', 'CL', 'IT')
	AND 	wnd.organization_id = :1
	AND 	wda.delivery_id = wnd.delivery_id
	AND  	wdd.delivery_detail_id = wda.delivery_detail_id
	AND 	wdd.source_code = 'OE'
	AND 	wdd.organization_id = :2
	AND 	wdd.source_header_id = jsl.header_id
	AND  	wdd.source_line_id = jsl.line_id
	AND 	((:3 = 'UN MATCH'
	AND 	EXISTS (select ref_line_id
			from 	JAI_CMN_MATCH_RECEIPTS
			where 	ref_line_id = wda.delivery_detail_id
			AND 	order_invoice ='O'
			and 	ship_status IS NULL) ) OR
	  	(:4 = 'MATCH'
	  	AND NOT EXISTS (select ref_line_id
	  			from 	JAI_CMN_MATCH_RECEIPTS
	  			where 	ref_line_id = wda.delivery_detail_id
	  			AND  	order_invoice ='O'
	  			and 	ship_status IS NULL) ) )
--	  AND 	wdd.customer_id = nvl(:5, wdd.customer_id )
--	  AND 	wdd.source_header_id = nvl(:6,wdd.source_header_id )
	  GROUP BY wda.delivery_id;

## MODIFICATION 2 customer_id is null and source_header_id is not null

SELECT /*+ MODIFICATION 2 CUSTOMER ID IS NULL AND SOURCE ID IS NOT NULL */ wda.delivery_id, count(wda.delivery_detail_id) delivery_detail_count
		FROM	wsh_new_deliveries wnd,
		wsh_delivery_assignments wda,
		wsh_delivery_details wdd,
		jai_om_oe_so_lines jsl
	WHERE 	wnd.status_code NOT IN ( 'CO', 'CL', 'IT')
	AND 	wnd.organization_id = :1
	AND 	wda.delivery_id = wnd.delivery_id
	AND  	wdd.delivery_detail_id = wda.delivery_detail_id
	AND 	wdd.source_code = 'OE'
	AND 	wdd.organization_id = :2
	AND 	wdd.source_header_id = jsl.header_id
	AND  	wdd.source_line_id = jsl.line_id
	AND 	((:3 = 'UN MATCH'
	AND 	EXISTS (select ref_line_id
			from 	JAI_CMN_MATCH_RECEIPTS
			where 	ref_line_id = wda.delivery_detail_id
			AND 	order_invoice ='O'
			and 	ship_status IS NULL) ) OR
	  	(:4 = 'MATCH'
	  	AND NOT EXISTS (select ref_line_id
	  			from 	JAI_CMN_MATCH_RECEIPTS
	  			where 	ref_line_id = wda.delivery_detail_id
	  			AND  	order_invoice ='O'
	  			and 	ship_status IS NULL) ) )
--	  AND 	wdd.customer_id = nvl(:5, wdd.customer_id )
	  AND 	wdd.source_header_id = :5
	  GROUP BY wda.delivery_id;

## MODIFICATION 4 customer_id is not null and source_header_id is not null

SELECT /*+ MODIFICATION 3 BOTH ARE NOT NULL COLUMNS */ wda.delivery_id, count(wda.delivery_detail_id) delivery_detail_count
		FROM	wsh_new_deliveries wnd,
		wsh_delivery_assignments wda,
		wsh_delivery_details wdd,
		jai_om_oe_so_lines jsl
	WHERE 	wnd.status_code NOT IN ( 'CO', 'CL', 'IT')
	AND 	wnd.organization_id = :1
	AND 	wda.delivery_id = wnd.delivery_id
	AND  	wdd.delivery_detail_id = wda.delivery_detail_id
	AND 	wdd.source_code = 'OE'
	AND 	wdd.organization_id = :2
	AND 	wdd.source_header_id = jsl.header_id
	AND  	wdd.source_line_id = jsl.line_id
	AND 	((:3 = 'UN MATCH'
	AND 	EXISTS (select ref_line_id
			from 	JAI_CMN_MATCH_RECEIPTS
			where 	ref_line_id = wda.delivery_detail_id
			AND 	order_invoice ='O'
			and 	ship_status IS NULL) ) OR
	  	(:4 = 'MATCH'
	  	AND NOT EXISTS (select ref_line_id
	  			from 	JAI_CMN_MATCH_RECEIPTS
	  			where 	ref_line_id = wda.delivery_detail_id
	  			AND  	order_invoice ='O'
	  			and 	ship_status IS NULL) ) )
	  AND 	wdd.customer_id = :5
	  AND 	wdd.source_header_id = :6
	  GROUP BY wda.delivery_id;

## MODIFICATION 4 customer_id is not null and source_header_id is null

SELECT /*+ MODIFICATION 4 CUSTOMER_ID is NOT NULL */ wda.delivery_id, count(wda.delivery_detail_id) delivery_detail_count
		FROM	wsh_new_deliveries wnd,
		wsh_delivery_assignments wda,
		wsh_delivery_details wdd,
		jai_om_oe_so_lines jsl
	WHERE 	wnd.status_code NOT IN ( 'CO', 'CL', 'IT')
	AND 	wnd.organization_id = :1
	AND 	wda.delivery_id = wnd.delivery_id
	AND  	wdd.delivery_detail_id = wda.delivery_detail_id
	AND 	wdd.source_code = 'OE'
	AND 	wdd.organization_id = :2
	AND 	wdd.source_header_id = jsl.header_id
	AND  	wdd.source_line_id = jsl.line_id
	AND 	((:3 = 'UN MATCH'
	AND 	EXISTS (select ref_line_id
			from 	JAI_CMN_MATCH_RECEIPTS
			where 	ref_line_id = wda.delivery_detail_id
			AND 	order_invoice ='O'
			and 	ship_status IS NULL) ) OR
	  	(:4 = 'MATCH'
	  	AND NOT EXISTS (select ref_line_id
	  			from 	JAI_CMN_MATCH_RECEIPTS
	  			where 	ref_line_id = wda.delivery_detail_id
	  			AND  	order_invoice ='O'
	  			and 	ship_status IS NULL) ) )
	  AND 	wdd.customer_id = :5
--	  AND 	wdd.source_header_id = nvl(:6,wdd.source_header_id )
	  GROUP BY wda.delivery_id;
</pre>
<p align="justify">The change require an IF..THEN..ELSE loop to check for the values of the Bind Variables at Run Time and execute the query that is relevant. With this change, the Optimizer calculated correct cardinality based on the predicates actually used by the User and came up with a perfect execution plan. Below is the plan, when the query was run at the customer site for both values as null.</p>
<pre>
Plan hash value: 466680131

------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                             |       |       |       |   114K(100)|          |
|   1 |  SORT GROUP BY                   |                             |     1 |    62 |       |   114K (59)| 00:00:01 |
|*  2 |   FILTER                         |                             |       |       |       |            |          |
|   3 |    NESTED LOOPS                  |                             |   511 | 31682 |       |   114K (59)| 00:00:01 |
|*  4 |     HASH JOIN                    |                             |   511 | 25550 |  2400K|   114K (59)| 00:00:01 |
|*  5 |      TABLE ACCESS BY INDEX ROWID | WSH_DELIVERY_DETAILS        | 64471 |  1636K|       | 62327  (59)| 00:00:01 |
|*  6 |       INDEX RANGE SCAN           | WSH_DELIVERY_DETAILS_TI6    |   142K|       |       |  4194  (91)| 00:00:01 |
|   7 |      NESTED LOOPS                |                             |       |       |       |            |          |
|   8 |       NESTED LOOPS               |                             | 72604 |  1701K|       | 48471  (55)| 00:00:01 |
|*  9 |        INDEX RANGE SCAN          | WSH_NEW_DELIVERIES_TI1      | 16146 |   204K|       |  2197  (91)| 00:00:01 |
|* 10 |        INDEX RANGE SCAN          | WSH_DELIVERY_ASSIGNMENTS_N1 |     5 |       |       |     0   (0)|          |
|  11 |       TABLE ACCESS BY INDEX ROWID| WSH_DELIVERY_ASSIGNMENTS    |     4 |    44 |       |     4  (50)| 00:00:01 |
|* 12 |     INDEX RANGE SCAN             | JAI_OM_OE_SO_LINES_N1       |     1 |    12 |       |     0   (0)|          |
|* 13 |    TABLE ACCESS BY INDEX ROWID   | JAI_CMN_MATCH_RECEIPTS      |     1 |    15 |       |     8  (50)| 00:00:01 |
|* 14 |     INDEX RANGE SCAN             | JAI_CMN_MATCH_RECEIPTS_N1   |     1 |       |       |     6  (50)| 00:00:01 |
|* 15 |    TABLE ACCESS BY INDEX ROWID   | JAI_CMN_MATCH_RECEIPTS      |     1 |    15 |       |     8  (50)| 00:00:01 |
|* 16 |     INDEX RANGE SCAN             | JAI_CMN_MATCH_RECEIPTS_N1   |     1 |       |       |     6  (50)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(((:B3='UN MATCH' AND  IS NOT NULL) OR (:B4='MATCH' AND  IS NULL)))
   4 - access("WDD"."DELIVERY_DETAIL_ID"="WDA"."DELIVERY_DETAIL_ID")
   5 - filter(("WDD"."SOURCE_CODE"='OE' AND "WDD"."SOURCE_HEADER_ID" IS NOT NULL))
   6 - access("WDD"."ORGANIZATION_ID"=:B2)
   9 - access("WND"."ORGANIZATION_ID"=:B1)
       filter(("WND"."STATUS_CODE"'IT' AND "WND"."STATUS_CODE"'CL' AND "WND"."STATUS_CODE"'CO'))
  10 - access("WDA"."DELIVERY_ID"="WND"."DELIVERY_ID")
       filter("WDA"."DELIVERY_ID" IS NOT NULL)
  12 - access("WDD"."SOURCE_LINE_ID"="JSL"."LINE_ID" AND "WDD"."SOURCE_HEADER_ID"="JSL"."HEADER_ID")
  13 - filter(("SHIP_STATUS" IS NULL AND "ORDER_INVOICE"='O'))
  14 - access("REF_LINE_ID"=:B1)
  15 - filter(("SHIP_STATUS" IS NULL AND "ORDER_INVOICE"='O'))
  16 - access("REF_LINE_ID"=:B1)
</pre>
<p align="justify">With the same indexes, but slight modification in the Query, the optimizer has come up with a plan that does a HASH Join (as against Nested Loop Join) based on the number of rows expected from WSH_DELIVERY_DETAILS Table.</p>
<p align="justify"><b>This modification was applied via an application patch, which resolved the Match Receipt Application Performance Issues. The benefit was due to the reduced number of Logical Reads.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/473/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=473&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2012/01/03/india-localization-r12-upgrade-performance-issues/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>How Challenging is the task of a Performance Optimization Expert ? A real life example&#8230;</title>
		<link>http://viveklsharma.wordpress.com/2011/11/19/how-challenging-is-the-task-of-a-performance-optimization-expert-a-real-life-example/</link>
		<comments>http://viveklsharma.wordpress.com/2011/11/19/how-challenging-is-the-task-of-a-performance-optimization-expert-a-real-life-example/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 16:45:10 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Cursor:Pin]]></category>
		<category><![CDATA[library cache lock]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=464</guid>
		<description><![CDATA[It is a well known fact that, most of the times, a Performance Optimization Expert is usually involved in Reactive mode. An Ongoing Performance Issue is easy to diagnose, but what if a severe performance issue was reported a day before and this caused a Crash of a production system ? In case of an [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=464&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">It is a well known fact that, most of the times, a Performance Optimization Expert is usually involved in Reactive mode. An Ongoing Performance Issue is easy to diagnose, but what if a severe performance issue was reported a day before and this caused a Crash of a production system ? </p>
<p align="justify">In case of an Issue that occured in the past, while most of the experts call for AWR reports and rely on ASH data available, but in my opinion, the analysis and recommendation based on AWR and ASH reports does not guarantee 100% accuracy. To prove this point, I have a real life scenario to share.</p>
<p align="justify">One of my customers added another node to an existing 2 node RAC production setup. Post completion of this activity, the system was released to the end users. In this case, end users are the customers across the globe. In the afternoon, severe slowness was reported and before anyone could analyze the issue, all the Application Servers / Web Servers Crashed and had to be restarted. There was a severe escalation and everyone pointed the finger of blame on the addition of a 3rd Node, as this was the only change in the entire production system. The Database Administrators also mentioned that while investigating the issue, they could observe severe “Cursor:pin” related waits. There were around 400+ sessions waiting for the “Cursor:pin” and the queries that were stuck were running successfully on other 2 nodes. Therefore, it was assumed to be a BUG or some issue related to 3rd Node. Since the Application architecture involved connections thru connection pool, when all the connections pool got exhausted, severe slowness and then a crash was reported.</p>
<p align="justify">A detailed investigation was initiated the next day. AWR report for the problem period and the ASH reports also revealed that almost 90% of the time the sessions were waiting on “Cursor:Pin” and the other 2 nodes the AWR was clean. While we were still investigating the issue, one of the DBA also mentioned that all other queries were working absolutely fine and, the problem only existed with the two tables as the queries on these 2 objects were waiting on the Mutexes and the executions of these queries were ZERO. The executions of the queries on these 2 objects were 1000+. Further, he also mentioned that they tried running the queries on these 2 objects from SQL*Plus, even these hung and had to be cancelled using CTRL-C. This raised some suspicion, as why the problem was only limited to 2 Objects and therefore, we started concentrating more these 2 Objects.</p>
<p><b>Analysis</b></p>
<p align="justify">These 2 Objects were actually a Synonym to 2 remote tables and 90% of the application modules get data from the remote database, using Database Link. Does it mean that during the problem period, there was some connectivity issue between the two Servers ? Let us simulate this with an example.</p>
<p align="justify">To simulate this, I created a database link between my 11g and 10g instance and then created a Synonym on EMP table, which resides in 10g Database. Further, to simulate production load, I created a database procedure that selects a row from this remote table and scheduled around 1000 sessions using DBMS_JOB. With the 10g Listener UP and Running, the job runs perfectly fine, therefore, I stopped the listener of 10g Database, as if there was some problem with the connectivity and re-scheduled the job.</p>
<pre>

connect vivek/vivek
create database link o10g connect to vivek identified by vivek using 'orcl10g';
create synonym emp_remote for emp@o10g;

create or replace procedure test_load as
e_name  varchar2(30);
l_eno	number;
begin
  l_eno:=round(dbms_random.value(7000,8000),0);
  select ename into e_name from emp_remote where empno=l_eno;
end;
/

alter session set nls_date_format='Dd-MM-YYYY HH24:MI:SS';

select sysdate from dual;

SYSDATE
-------------------
15-11-2011 00:45:42

## I Scheduled the Jobs to run at 00 Hours &amp; 47 Minutes

declare
l_job	number;
begin
   for i in 1..1000
     loop

       dbms_job.submit(l_job,'test_load;',trunc(sysdate)+00/24+47/(24*60));
       commit;
     end loop;
end;
/
</pre>
<p>Once the Jobs started, the wait events and the execution of the query hung on &#8220;Cursor:Pin&#8221; are as under :</p>
<pre>
       SID EVENT                                  P1         P2         P3 SQL_ID
---------- ------------------------------ ---------- ---------- ---------- -------------
         1 pmon timer                            300          0          0
         4 DIAG idle wait                          5          1       1000
        10 Streams AQ: qmn coordinator id          0          0          0
        13 Streams AQ: qmn slave idle wai          1          0          0
        15 Streams AQ: waiting for time m          0          0          0
        26 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        28 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        30 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        32 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        34 library cache lock             1269367872 1235709864          2 f20gyq4m5fh3c
        35 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        42 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        47 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        49 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        51 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
        52 library cache lock             1269367872 1235628808          2 f20gyq4m5fh3c
        54 library cache lock             1269367872 1269117072          2 f20gyq4m5fh3c
       125 VKRM Idle                               0          0          0
       126 VKTM Logical Idle Wait                  0          0          0
       127 DIAG idle wait                          5          1       1000
       131 smon timer                            300          0          0
       136 Space Manager: slave idle wait          0          0          0
       139 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       142 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       143 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       149 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       153 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       154 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       155 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       156 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       170 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       172 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c
       175 library cache lock             1269367872 1234978972          2 f20gyq4m5fh3c
       176 cursor: pin S wait on X         643252332   10682368     327680 f20gyq4m5fh3c

SQL&gt; @sql_sqlid
Enter value for sql: f20gyq4m5fh3c
old   1: select sql_id, sql_text, executions, buffer_gets from v$sqlarea where sql_id='&amp;sql'
new   1: select sql_id, sql_text, executions, buffer_gets from v$sqlarea where sql_id='f20gyq4m5fh3c'

SQL_ID        SQL_TEXT                                           EXECUTIONS BUFFER_GETS
------------- -------------------------------------------------- ---------- -----------
f20gyq4m5fh3c SELECT ENAME FROM EMP_REMOTE WHERE EMPNO=:B1                0           0
</pre>
<p align="justify">This was the exact behaviour that was reported on the 3rd Node production setup. I compared the alert.log of my Database and the production 3rd Node and the common observation was an entry in both the environment (this is from my database). In production, the error was related to tns timeout.</p>
<pre>

Fatal NI connect error 12541, connecting to:
 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost.localdomain)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl10g)(CID=(PROGRAM=oracle)(HOST=localhost.localdomain)(USER=oracle))))

  VERSION INFORMATION:
        TNS for Linux: Version 11.2.0.1.0 - Production
        TCP/IP NT Protocol Adapter for Linux: Version 11.2.0.1.0 - Production
  Time: 15-NOV-2011 01:01:30
  Tracing not turned on.
  Tns error struct:
    ns main err code: 12541

TNS-12541: TNS:no listener
    ns secondary err code: 12560
    nt main err code: 511

TNS-00511: No listener
    nt secondary err code: 111
    nt OS err code: 0
</pre>
<p align="justify">At this point, when we discussed this with the customer, one of the Application team member admitted that as a part of the checklist, they missed out on Opening of a Port from the database server to the Server hosting the remote database and this was realized in the afternoon. They were not aware of the implication it had on the production setup.</p>
<p align="justify">In this case, the AWR &amp; ASH reports revealed &#8220;Cursor:Pin&#8221; waits but were not sufficient in revealing the actual cause of the issue. It required further analysis, therefore, I usually insist on production access to diagnose a Performance Issue whether it was in the past or is an ongoing issue.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/464/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=464&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/11/19/how-challenging-is-the-task-of-a-performance-optimization-expert-a-real-life-example/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>AIOUG Annual Event Sangam 2011</title>
		<link>http://viveklsharma.wordpress.com/2011/10/18/aioug-annual-event-sangam-2011/</link>
		<comments>http://viveklsharma.wordpress.com/2011/10/18/aioug-annual-event-sangam-2011/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 09:48:57 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[AIOUG]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=458</guid>
		<description><![CDATA[All India Oracle User Group is back with its Annual Conference and this time, it is back to Bangalore. The event, Sangam 2011, will be held on 9th and 10th of December 2011. This time, Arup Nanda will be presenting 2 half days session. Apart from Arup, there are several other speakers who would be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=458&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">All India Oracle User Group is back with its Annual Conference and this time, it is back to Bangalore. The event, Sangam 2011, will be held on 9th and 10th of December 2011. This time, Arup Nanda will be presenting 2 half days session. Apart from Arup, there are several other speakers who would be presenting and this again makes the event an Interesting one to attend. This time though I am not presenting, I will be attending both the days as it gives me an oppurtunity to meet up the Oracle Community. Visit www.aioug.org to register for the event. See you in Bangalore <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/458/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=458&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/10/18/aioug-annual-event-sangam-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>parse count (failures) &#8211; How do I find queries causing failures ?</title>
		<link>http://viveklsharma.wordpress.com/2011/09/20/parse-count-failures-how-do-i-find-queries-causing-failures/</link>
		<comments>http://viveklsharma.wordpress.com/2011/09/20/parse-count-failures-how-do-i-find-queries-causing-failures/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 05:22:25 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[Library Cache]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=453</guid>
		<description><![CDATA[In my last blog on Hard Parses and failures posted on September 3, 2011, I missed to write about the ways to find the Queries causing &#8220;parse count (failures)&#8221;. I received few mails from some of readers wanting to know on how to get these. Since these queries fail, these are not stored in the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=453&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">In my last blog on Hard Parses and failures posted on September 3, 2011, I missed to write about the ways to find the Queries causing &#8220;parse count (failures)&#8221;. I received few mails from some of readers wanting to know on how to get these. Since these queries fail, these are not stored in the Shared Pool and therefore, it is not possible to get these from v$ views. Secondly, since these are not stored in the Shared Pool, everytime these queries are executed, these are hard parsed, thus causing unwanted contention on Library Cache latches.</p>
<p align="justify">A possible way to get these is 10046 traces. I used these traces to get the Queries that were causing these failures to occur. Yesterday, I was working at another customer site, where I could see some failures happening. These are again around 25% to 30% of the total Hard Parses. Therefore, if we eliminate these, total hard parses / second would come down. Following query helps me check, whether the statistics related to hard parses are alarming.</p>
<pre>
set linesize 132
alter session set nls_date_format='DD-MM-YYYY HH24:MI:SS';
select sysdate, name, value from v$sysstat where name like 'parse%';
exec dbms_lock.sleep(10);
select sysdate, name, value from v$sysstat where name like 'parse%';
</pre>
<p align="justify">I execute a query against v$sysstat, wait for 10 seconds and re-execute the same. Therefore, the incremental figure is for 10 seconds duration. From this, it is very easy to compute the parses/second ratio. Following is the output of the query taken yesterday :</p>
<pre>
SQL&gt; @hard_parse

Session altered.

Elapsed: 00:00:00.00

SYSDATE             NAME                                                                  VALUE
------------------- ---------------------------------------------------------------- ----------
20-09-2011 10:28:14 parse time cpu                                                       117213
20-09-2011 10:28:14 parse time elapsed                                                   390923
20-09-2011 10:28:14 parse count (total)                                                54294681
20-09-2011 10:28:14 parse count (hard)                                                   766713
20-09-2011 10:28:14 parse count (failures)                                               177555
20-09-2011 10:28:14 parse count (describe)                                                  204

6 rows selected.

Elapsed: 00:00:00.03

PL/SQL procedure successfully completed.

Elapsed: 00:00:10.00

SYSDATE             NAME                                                                  VALUE
------------------- ---------------------------------------------------------------- ----------
20-09-2011 10:28:24 parse time cpu                                                       117216
20-09-2011 10:28:24 parse time elapsed                                                   390969
20-09-2011 10:28:24 parse count (total)                                                54303954
20-09-2011 10:28:24 parse count (hard)                                                   767011
20-09-2011 10:28:24 parse count (failures)                                               177637
20-09-2011 10:28:24 parse count (describe)                                                  204

6 rows selected.

Elapsed: 00:00:00.02
SQL&gt; select 767011-766713, 177637-177555 from dual;

767011-766713 177637-177555
------------- -------------
          298            82
</pre>
<p align="justify">In this case, the Hard Parses are 29.8 per second and failures are 8.2, which is around 28% of the total hard parses. To check for the queries causing these, I generated enabled 10046 trace at system level, during less concurrency time (non-peak hours), and issued <b>grep -i &#8220;PARSE ERROR&#8221; *.trc</b>. This gave me the name of the trace files and from these traces, it was very easy to figure out the queries that were failing. In the trace file, search for PARSE ERROR and you will get the query, alongwith the reason for its failure, which is ora-942 (table or view does not exists), as can be seen in err column.</p>
<pre>
grep -i "PARSE ERROR" *.trc
RAC1_ora_1966688.trc:PARSE ERROR #1:len=157 dep=0 uid=38 oct=3 lid=38 tim=2611876001420 err=942
RAC1_ora_1966688.trc:PARSE ERROR #1:len=157 dep=0 uid=38 oct=3 lid=38 tim=2611876029670 err=942
RAC1_ora_1966688.trc:PARSE ERROR #5:len=95 dep=1 uid=0 oct=3 lid=0 tim=2611876430154 err=942
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/453/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/453/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/453/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/453/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/453/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/453/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/453/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/453/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=453&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/09/20/parse-count-failures-how-do-i-find-queries-causing-failures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>Do we need to take care of Hard Parses only when Library Cache related Latches are on top ?</title>
		<link>http://viveklsharma.wordpress.com/2011/09/03/do-we-need-to-take-care-of-hard-parses-only-when-library-cache-related-latches-are-on-top/</link>
		<comments>http://viveklsharma.wordpress.com/2011/09/03/do-we-need-to-take-care-of-hard-parses-only-when-library-cache-related-latches-are-on-top/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 20:05:55 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[Library Cache]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[connection pool]]></category>
		<category><![CDATA[Hard Parse]]></category>
		<category><![CDATA[Shared Pool]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=446</guid>
		<description><![CDATA[I just concluded a 3 months Production Optimization Project. The problem summary was an overall slowness of the production system, which is a three tier architecture. The Production System includes a 2 Node 10.2.0.5 Database with 4 Application Servers configured with Connection Pool. As with all my Performance Project, this time too I started off [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=446&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">I just concluded a 3 months Production Optimization Project. The problem summary was an overall slowness of the production system, which is a three tier architecture. The Production System includes a 2 Node 10.2.0.5 Database with 4 Application Servers configured with Connection Pool. As with all my Performance Project, this time too I started off with a one round of discussion with all the stake holders. These stake holders manage the production system and were called upon to express their opinion on the overall slowness. While everyone voiced together that the slowness is consistent the entire day, they also mentioned that they are confident that the issue is with the Oracle Application Server and the way it manages the Connection Pool. The rationale behind this assumption was the Connection Pool Statistics, which says that as the load increases, the number of Connection Pools configured increase drastically and are not freed until the load comes down. The peak starts at 11 am and, since the production system is slow, the load comes down by 9 pm. The business hours of the customer is 9 am to 5 pm.</p>
<p align="justify">Initial investigation revealed that with Automatic Shared Memory Management enabled, the Shared Pool had grown upto 40GB. This is pretty high. I have not seen any configuration that requires such a huge Shared Pool. This was surely a cause of concern and therefore, this was further drilled down to one of a serious bug in the application. This was <b>Hard Parse</b>.</p>
<p align="justify">An Application or Database flooded with Unshared Application queries is considered as an Unscalable Application. Slowly or Gradually, as the User Load increase, the performance issues are bound to come. In this case, the Hard Parse / Second ratio was around 180 per second. While there were many queries that were using Literals, the most surprising part was the Hard Parse failures, which were almost 68% of the total Hard Parses. Therefore, once a patch to fix the queries that were using Literals was applied, there was no significant improvement.</p>
<p align="justify">The most challenging part of this assignment was the reluctance from the Application Team to accept the Hard Parses or the Parse failure to be an Issue. The debate from the Application Team was that reducing the Hard Parses would not yield any benefit as they do not see any Library Cache related latches on top. They have been taught to see the AWR reports and look to the top events. Reducing the number of waits of the top most component seemed to be on top of the list for Application team. While this is true, to some extent, but in case of Hard Parses, this would not work.</p>
<p align="justify">This is the reason, the title of my blog is <b>&#8220;Do we really need to take care of Hard Parses only when Library Cache related Latches are on top ?&#8221;</b>. In this case, the Hard Parses can be easily related to the contention that we observed on the Connection Pool. Usually, the response time of a Connection Pool or a Shared Server Architecture should be less than a Second. If this goes high, we might see a slowness or contention on Connection Pool, as other users may have to wait for the pool to be released. This again explains, why the number of connections pools increased as the load increases.</p>
<p align="justify">Hard Parses are a performance killer, also called as a Silent Killer. Many a times, Hard Parses does not cause significant waits on Library Cache latches. It depends on the resources available at the Database Server. In this case, it was a 2 Node RAC with 56 CPU&#8217;s on each machine. The Hardware configuration was enough and therefore, the contention was not that significant to cause Latch Free waits. As we all know, Hard Parse takes more time than a Soft Parse or a No Parse and this resulted in a signifcant waits or contention on Connection Pool. Also, as mentioned above, Hard Parses are Silent Killer. With that said, if these are not taken care of at a initial stage, this can bring down the Production System (as it did in the case of my Customer).</p>
<p align="justify">To summarize, Hard Parses are to be addressed even if these are not visible as a Latch Contention. In case of my customer, as soon as the Hard Parses and Parse failures were fixed, the performance of the production system improved drastically and was consistent through out the day. The users were able to enter their transactions in the business hours. Further, the contention on the connection pool came down as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/446/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=446&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/09/03/do-we-need-to-take-care-of-hard-parses-only-when-library-cache-related-latches-are-on-top/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>What has triggered this Sudden Performance Degradation ? A Generic Question&#8230;</title>
		<link>http://viveklsharma.wordpress.com/2011/06/13/what-has-triggered-this-sudden-performance-degradation-a-generic-question/</link>
		<comments>http://viveklsharma.wordpress.com/2011/06/13/what-has-triggered-this-sudden-performance-degradation-a-generic-question/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 07:44:15 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[AIOUG]]></category>
		<category><![CDATA[Optimizer]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=424</guid>
		<description><![CDATA[It is a well known fact that most of the time, a Performance Tuning Consultant is involved for a Reactive Support which is due to a severe performance issue. During such involvement, one of the generic question that a Performance Tuning Expert or Consultant has to answer is &#8220;What has triggered this Sudden Performance Degradation [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=424&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">It is a well known fact that most of the time, a Performance Tuning Consultant is involved for a Reactive Support which is due to a severe performance issue. During such involvement, one of the generic question that a Performance Tuning Expert or Consultant has to answer is &#8220;What has triggered this Sudden Performance Degradation ?&#8221; or a Comment like &#8220;Oracle Optimizer is an Issue as it triggered this Degradation and everything came back to normalcy after reverting the Optimizer Stats&#8221;. The challenge for the Consultant is to prove that Optimizer is not an Issue and it is the Application behaviour or Indexing Strategy that has caused this issue. This Strategy acted as a slow poison and then a point reached when it finally gave up. During one of my presentation at All India Oracle User Group, I presented on Developing a Scalable Application and this was one of my slide, which I felt would be of use for my readers as well.</p>
<p align="justify">In this blog, I will answer to the Question and Comment mentioned above. This would be one of the case that can trigger a sudden degradation. The test case will be around Optimizer Statistics. I have been asked this question by the Customers and concerns were raised over the way Optimizer works or use these Statistics. Some of the Concerns raised are :</p>
<p align="justify">
<ol>
<li>Why do I generate fresh Stats when I am Satisfied by the Application Performance on current Stats ?</li>
<li>I generated Statistics over the weekend and suddenly the performance degraded. Finally, I reverted back the statistics and everything came back to normalcy.</li>
<li>What is the cause of this Sudden Degradation ?</li>
</ol>
<p align="justify">While lot has been written on Concern 1 (the way Optimizer works and the change in Optimizer behaviour in 10g, I will answer Concern 2, and Concern 3 will be automatically answered. As usual, all this will be well supported and demonstrated by way of a Test Case.</p>
<p><b>SCENARIO</b></p>
<p align="justify">A Customer gathered Statistics on all the production tables. As per the policy, these statistics are gathered every weekend since last couple of years. On Monday, suddenly the Users started complaining about the slowness. The Onsite DBA&#8217;s had a look at the system and complained about the I/O issue. Further investigations revealed that the Execution plans for some of the critical application queries has changed from Index Scan to Full Table Scan. What has changed between Friday and Monday? The DBA&#8217;s realised that the only change is Optimizer Statistics. In such cases, if it is possible to identify the suspected table and its stats, then it is very easy to revert the stats of this table else the option left out is to revert the entire statistics and bring back the stats of Friday. Both the fallback plan has its own Implications. After reverting the Statistics, the Application Performance comes back to normalcy. Based on the cause of the Issue and the change to get back to normalcy, it is quite evident that the finger of blame would be on Oracle Optimizer. The Customer then decided not to gather fresh statistics unless the Optimizer Issue is resolved.</p>
<p align="justify">While there are various reasons that can cause a Slowness post-fresh statistics generation, one of the top most cause is Inefficient Indexing. If the Indexing Strategy of an Application is not optimal, the performance of that application would show a sudden degradation. Usually, Performance drop is not linear. It is always exponential, when the utilization reaches a threshold where it is difficult to handle the extra (minor) growth, this minor growth is enough to cause a sudden degradation.</p>
<p><b>TEST CASE &amp; EXPLANATION</b></p>
<p align="justify">To Demonstrate the impact of In-efficient Indexing, we need to make certain assumption. In this case, let us assume that the Production System has just gone live and the production tables were without any rows, except the Master Tables. For our demonstration, I will create a table and populate some data (initially 10 days) and run an application query against that table. The table is setup to create 10 Customer ID&#8217;s and each of these customers have 5 transactions a day. We will run an application query to get the product_name and sale_value for a Customer for a day. This query should return 5 rows from initial 500 rows (10 Days x 5 Transactions a day x 10 Customers).</p>
<p align="justify">Next, as the system become 60 days old, the same application query is run. In our case, even if the volume increase, the number of rows return by the query remains unchanged. We shall see the significant impact of this Increase in Volume on the Performance and this impact was all of a sudden.
<pre>
<b><u>Table Creation Script - Inserts 10 days Data, which means the production is 10 days old</u></b>

exec dbms_random.seed(0);
drop table vivek_test;
create table vivek_test as
with main as
(select mod(rownum,10) custid,
        round(dbms_random.value(1000,7000),0) sale_value,
        dbms_random.string('A',20) product_name
from    all_objects a
where rownum&lt;=50)
select custid, s_date sale_date, sale_value, product_name
from    main, (select sysdate - level s_date from dual connect by level&lt;=10) ;

<b><u>Next we Create an Index on CustID and Gather Statistics</u></b>

create index vivek_test_idx on vivek_test(custid);
exec dbms_stats.gather_table_stats(user,'VIVEK_TEST',cascade=&gt;true,method_opt=&gt;'for all columns size 1');

<b><u>Once this is done, we execute our Application Query to get data for 09th June 2011</u></b>

variable b1 varchar2(20);
exec :b1:='06-09-2011';

select /*+ vivek */ custid, product_name, sale_value
from  vivek_test
where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60);

    CUSTID PRODUCT_NAME         SALE_VALUE
---------- -------------------- ----------
         1 rMLTDXxxqXOZnqYRJwIn       1380
         1 AOcitwrWNXCxPHzIIIxw       3850
         1 hpalFVIprLxIHDrRgqHb       2287
         1 vkfKdaFoCaHgBCQAFgCY       4364
         1 DAlVYefHAurNoryMikSJ       1125

<b><u>Runtime Plan</u></b>

select sql_id, sql_text, buffer_gets, executions, version_count
from v$sqlarea where sql_text like 'select /*+ vivek%';

SQL_ID        SQL_TEXT                                           BUFFER_GETS EXECUTIONS VERSION_COUNT
------------- -------------------------------------------------- ----------- ---------- -------------
2t8mwg94j89h8 select /*+ vivek */ custid, product_name, sale_val          10          2             1
              ue from  vivek_test where custid=1 and   sale_date
               between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and
              to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------
SQL_ID  2t8mwg94j89h8, child number 0
-------------------------------------
select /*+ vivek */ custid, product_name, sale_value from  vivek_test where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and
to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60)

Plan hash value: 2623397998

-----------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |       |       |     4 (100)|          |
|*  1 |  FILTER                      |                |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID| VIVEK_TEST     |     1 |    35 |     4   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | VIVEK_TEST_IDX |    50 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(TO_DATE(:B1,'MM-DD-YYYY HH24:MI:SS')=TO_DATE(:B1,'MM-DD-YYYY HH24:MI:SS') AND
              "SALE_DATE"&lt;=TO_DATE(:B1,&#039;MM-DD-YYYY HH24:MI:SS&#039;)+1-.0000115740740740740740740740740740
              7407407407))
   3 - access(&quot;CUSTID&quot;=1)
</pre>
<p align="justify">The Runtime Plan in this case shows that the Application Query has used an Index on Custid, which is usually an appropriate approach in an OLTP system. The Interesting fact here is a Throwaway, which is, 50 Rows were fetched from an Index and only 1 row was fetched from the Table Access. In this case, 49 rows were THROWNAWAY. The Actual THROWAWAY rows are 45, but again, 45 rows out of 50 rows is 90% of the rows are discarded and this is very bad.</p>
<p><b>THE REAL PERFORMANCE ISSUE</B></p>
<p align="justify">User Continue to use the system and it is now 60 days old. As per the policy, after the 60th day, fresh Statistics were gathered. Further, the DBA&#8217;s also take the backup of the old stats before generating new. As the data is entered, users also continue to execute the application query.</p>
<pre>
truncate table vivek_test;
exec dbms_random.seed(0);

insert into vivek_test
with main as
(select mod(rownum,10) custid,
        round(dbms_random.value(1000,7000),0) sale_value,
        dbms_random.string('A',20) product_name
from    all_objects a
where rownum&lt;=50)
select custid, s_date sale_date, sale_value, product_name
from    main, (select sysdate - level s_date from dual connect by leveltrue,method_opt=&gt;'for all columns size 1');

exec dbms_stats.create_stat_table(user,'STATS');
exec dbms_stats.export_table_stats(user,'VIVEK_TEST',stattab=&gt;'stats');

variable b1 varchar2(20);
exec :b1:='06-09-2011';

select /*+ vivek */ custid, product_name, sale_value
from  vivek_test
where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60);

<b><u>Run time Plan</u></b>
Plan hash value: 2623397998
-----------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |       |       |    18 (100)|          |
|*  1 |  FILTER                      |                |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID| VIVEK_TEST     |    15 |   525 |    18   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | VIVEK_TEST_IDX |   300 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
</pre>
<p align="justify">Check for the Throwaway percentage now, which has gone up considerably. Let us pump in 5 (for 5 working days) days data, and as per the policy, generate fresh statistics. We already have a backup of the previously generated Statistics in STATS table. </p>
<pre>
truncate table vivek_test;
exec dbms_random.seed(0);

insert into vivek_test
with main as
(select mod(rownum,10) custid,
        round(dbms_random.value(1000,7000),0) sale_value,
        dbms_random.string('A',20) product_name
from    all_objects a
where rownum&lt;=50)
select custid, s_date sale_date, sale_value, product_name
from    main, (select sysdate - level s_date from dual connect by leveltrue,method_opt=&gt;'for all columns size 1');

variable b1 varchar2(20);
exec :b1:='06-09-2011';

select /*+ vivek */ custid, product_name, sale_value
from  vivek_test
where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60);

<b><u>Run time Plan</u></b>
Plan hash value: 1579208797

---------------------------------------------------------------------------------
| Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |            |       |       |    18 (100)|          |
|*  1 |  FILTER            |            |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| VIVEK_TEST |    15 |   525 |    18   (0)| 00:00:01 |
---------------------------------------------------------------------------------
</pre>
<p align="justify">In just 4-5 days, the plan of the query changed from Index Scan to Full Table Scan. Further, the I/O&#8217;s of the query also increased from 10 (when it started) to 22 and then now to 63 per execution. The Cost of the Query remains same. In high concurrency, these Full table Scan&#8217;s would surely have an impact on the overall performance. Let us now revert the statistics from the backup table and check for the query performance.</p>
<pre>
<b><u>Current Stats</u></b>
new   2: where table_name='VIVEK_TEST'

OWNER                          PAR   NUM_ROWS     BLOCKS LAST_ANAL GLO
------------------------------ --- ---------- ---------- --------- ---
VIVEK                          NO        3250         60 13-JUN-11 YES

Elapsed: 00:00:00.45
SQL&gt; exec dbms_stats.import_table_stats(user,'VIVEK_TEST',stattab=&gt;'STATS');

PL/SQL procedure successfully completed.

Elapsed: 00:00:01.04

<b><u>Reverted Stats</u></b>
OWNER                          PAR   NUM_ROWS     BLOCKS LAST_ANAL GLO
------------------------------ --- ---------- ---------- --------- ---
VIVEK                          NO        3000         60 13-JUN-11 YES

variable b1 varchar2(20);
exec :b1:='06-09-2011';

select /*+ vivek */ custid, product_name, sale_value
from  vivek_test
where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60);

<b><u>Runtime Plan</u></b>
Plan hash value: 2623397998

-----------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |       |       |    18 (100)|          |
|*  1 |  FILTER                      |                |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID| VIVEK_TEST     |    15 |   525 |    18   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | VIVEK_TEST_IDX |   300 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
</pre>
<p align="justify">After the Statistics were reverted, the application query regenerated the Better plan. This was enough to raise a doubt over the behaviour of Optimizer. On my test database, the actual issue occured on the 61st day. In your case, this may not be the case. For this example, I will also demonstrate you a way to find out on which day the Optimizer will change the plan.</p>
<p align="justify">The test case and demonstration clearly explains that the issue here is not because of the Optimizer Statistics, but is because of Inefficient Indexing, which is also evident from the Throwaway percentage mentioned above. To prove this point, I will create a composite index on Custid, sale_date. I will generate a fresh statistics, which will for 65 days. Once the Application query is run, I will pump in 365 days worth of data, regenerate fresh statistics and check for the Execution Plan (and throwaway percentage).</p>
<pre>
drop index vivek_test_idx;
create index vivek_test_idx on vivek_test(custid, sale_date);
exec dbms_stats.gather_table_stats(user,'VIVEK_TEST',cascade=&gt;true,method_opt=&gt;'for all columns size 1');
variable b1 varchar2(20);
exec :b1:='06-09-2011';

select /*+ vivek */ custid, product_name, sale_value
from  vivek_test
where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60);

SQL_ID        SQL_TEXT                                           BUFFER_GETS EXECUTIONS VERSION_COUNT
------------- -------------------------------------------------- ----------- ---------- -------------
2t8mwg94j89h8 select /*+ vivek */ custid, product_name, sale_val           6          1             1
              ue from  vivek_test where custid=1 and   sale_date
               between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and
              to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60
              )

Plan hash value: 2623397998
-----------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |       |       |     5 (100)|          |
|*  1 |  FILTER                      |                |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| VIVEK_TEST     |    15 |   525 |     5   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | VIVEK_TEST_IDX |    16 |       |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------

<b><u>The Production is now a year old, with new Index</u></b>
truncate table vivek_test;
exec dbms_random.seed(0);

insert into vivek_test
with main as
(select mod(rownum,10) custid,
        round(dbms_random.value(1000,7000),0) sale_value,
        dbms_random.string('A',20) product_name
from    all_objects a
where rownum&lt;=50)
select custid, s_date sale_date, sale_value, product_name
from    main, (select sysdate - level s_date from dual connect by leveltrue,method_opt=&gt;'for all columns size 1');

select /*+ vivek */ custid, product_name, sale_value
from  vivek_test
where custid=1
and   sale_date between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60);

SQL_ID        SQL_TEXT                                           BUFFER_GETS EXECUTIONS VERSION_COUNT
------------- -------------------------------------------------- ----------- ---------- -------------
2t8mwg94j89h8 select /*+ vivek */ custid, product_name, sale_val           6          1             1
              ue from  vivek_test where custid=1 and   sale_date
               between to_date(:b1,'MM-DD-YYYY HH24:MI:SS') and
              to_date(:b1,'MM-DD-YYYY HH24:MI:SS')+1-1/(24*60*60
              )

Plan hash value: 2623397998
-----------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |       |       |     5 (100)|          |
|*  1 |  FILTER                      |                |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| VIVEK_TEST     |    15 |   525 |     5   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | VIVEK_TEST_IDX |    15 |       |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
</pre>
<p align="justify">With the New Index, the performance is consistent and the performance matrix (I/O&#8217;s and throwaway percentage) are stable too. This answers the concern raised by the Customers <b>&#8220;What is the cause of Sudden Degration ?&#8221;</b>. In most of the cases, the change in behaviour is due to Application. You may notice that the change in number of rows from 3000 to 3250 (a difference of 250 rows) could cause the performance degradation. In this case, the number of blocks remained unchanged. As mentioned earlier, in my test case, it was the 61st day that triggered the plan change, which means, addition of just 50 rows. On an actual OLTP production system, the number of rows inserted on a day into a table is huge.</p>
<p align="justify">You may run the following pl/sql block on your test database to check the day on which the execution plan of above query would change.</p>
<pre>
drop index vivek_test_idx;
create index vivek_test_idx on vivek_test(custid);
<b><u>This is for 120 Days and Statement Id from plan_table corresponds to the day.</u></b>

declare
s_date	varchar2(30):=to_char(trunc(sysdate)-1,'MM-DD-YYYY');
e_date  varchar2(30):=to_char(trunc(sysdate)+1-1/(24*60*60),'MM-DD-YYYY');
l_stat	varchar2(1000);
begin
  execute immediate 'delete from plan_table';
  for i in 1..120
  loop
   execute immediate 'truncate table vivek_test';
   insert into vivek_test
   with main as
   (select mod(rownum,10) custid,
           round(dbms_random.value(1000,7000),0) sale_value,
           dbms_random.string('A',20) product_name
   from    all_objects a
   where rownum&lt;=50)
   select custid, s_date sale_date, sale_value, product_name
   from    main, (select sysdate - level s_date from dual connect by leveltrue,method_opt=&gt;'for all columns size 1');
   l_stat:= 'explain plan set statement_id '||''''||i||''''||' for select custid, sale_value, sale_date from vivek_test where custid=1
            and   sale_date between to_date(:b2,'||''''||'MM-DD-YYYY HH24:MI:SS'||''''||')
            and to_date(:b3,'||''''||'MM-DD-YYYY HH24:MI:SS'||''''||')';
    execute immediate l_stat using s_date, e_date;
--    dbms_output.put_line(l_stat);
   commit;
  end loop;
end;
/
column operation for a20
column options for a20
select statement_id, operation, options from plan_table
where operation='TABLE ACCESS'
order by to_number(statement_id);

STATEMENT_ID                   OPERATION            OPTIONS
------------------------------ -------------------- --------------------
1                              TABLE ACCESS         BY INDEX ROWID
2                              TABLE ACCESS         BY INDEX ROWID
3                              TABLE ACCESS         BY INDEX ROWID

56                             TABLE ACCESS         BY INDEX ROWID
57                             TABLE ACCESS         BY INDEX ROWID
58                             TABLE ACCESS         BY INDEX ROWID
59                             TABLE ACCESS         BY INDEX ROWID
60                             TABLE ACCESS         BY INDEX ROWID
61                             TABLE ACCESS         FULL &lt;---- From 61st Day, the Plan Changed
62                             TABLE ACCESS         FULL
63                             TABLE ACCESS         FULL
64                             TABLE ACCESS         FULL

120                            TABLE ACCESS         FULL

120 rows selected.
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/424/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/424/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/424/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/424/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/424/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/424/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/424/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/424/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=424&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/06/13/what-has-triggered-this-sudden-performance-degradation-a-generic-question/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>Exadata v/s Traditional Storage</title>
		<link>http://viveklsharma.wordpress.com/2011/03/14/exadata-vs-traditional-storage/</link>
		<comments>http://viveklsharma.wordpress.com/2011/03/14/exadata-vs-traditional-storage/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 20:09:23 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=419</guid>
		<description><![CDATA[My previous blog was on Exadata and I demonstrated the use of Oracle API&#8217;s to simulate Exadata Performance on a Traditional Storage. I am now all set to witness the actual performance benefits that Exadata Storage can provide, when compared to other storages. Currently, I am engaged for the same customer where I presented a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=419&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">My previous blog was on Exadata and I demonstrated the use of Oracle API&#8217;s to simulate Exadata Performance on a Traditional Storage. I am now all set to witness the actual performance benefits that Exadata Storage can provide, when compared to other storages. Currently, I am engaged for the same customer where I presented a Simulation that looked encouraging and this time, I am involved in a Benchmarking of an Entire Application Performance on the Exadata Box. The Application is a mix of OLTP and Batch processes and the results are awaited in next few days time. Would share some of the interesting facts soon.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/419/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/419/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/419/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/419/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/419/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/419/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/419/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/419/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=419&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/03/14/exadata-vs-traditional-storage/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>Simulating Exadata Storage Performance over Traditional Storage</title>
		<link>http://viveklsharma.wordpress.com/2011/01/03/simulating-exadata-storage-performance-over-traditional-storage/</link>
		<comments>http://viveklsharma.wordpress.com/2011/01/03/simulating-exadata-storage-performance-over-traditional-storage/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 10:59:11 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=414</guid>
		<description><![CDATA[Exadata Server Storage Software plays a crucial role in delivering Extreme Performance and Scalability for all database Application and this includes OLTP, Datawarehouse and mix of both. Performance bottleneck, due to data growth and Increase in the Userbase, the customers are now aware of the fact that they need to adopt this technology. There have [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=414&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Exadata Server Storage Software plays a crucial role in delivering Extreme Performance and Scalability for all database Application and this includes OLTP, Datawarehouse and mix of both. Performance bottleneck, due to data growth and Increase in the Userbase, the customers are now aware of the fact that they need to adopt this technology. There have been instances when Customers, especially in India, request a POC to measure the performance benefit of EXADATA over Traditional Storage. Starting Oracle 11g R2, Oracle provides certain API&#8217;s that can be give a fair amount of accurate performance statistics for the application queries and the way these will behave post-implementing exadata. This can also be done using Oracle Enterprise Manager 11g, but I used Oracle API&#8217;s to simulate and get the exadata performance matrix on a production system at a customer site.</p>
<p align="justify">One of my customer is evaluating Oracle Exadata and the mandate, in this case, is clearly increasing Market competition and sustenance. While the team were busy preparing a presentation, we felt, it would be a good idea to present the customer with the artifacts of the benefits in the actual production queries from their own production system. Post running these scripts a text file was presented to the customer. The customer was amazed to see the performance benefits.</p>
<p align="justify">Before we get into the API&#8217;s, a brief explanation on Exadata. EXADATA is a fully loaded Server, that comes in different configuration and is plug-and-play machine. It is basically an storage aware software and this intelligence is built in Storage Cells. These Cells store the data they contain and therefore, it is easier to get into the data block that contain the relevant rows directly. Unlike traditional storage that returns all the blocks to the Database Server, Exadata Storage Software returns only the relevant blocks that contain the data. Therefore, the main performance gain observed is due to the amount of data that travels between the Storage System and Database Server. Usually, the I/O bottleneck is observed in the production system if the amount of data that travels is enormous. With Exadata, these unwanted data is filtered at the storage level itself and relevant data traverses from the I/O subsystem to the Database Server. Further, its also reduces the amount of Latching, that would have otherwise required, to protect the blocks reads from the Storage into the SGA. Reduction in Latch Gets means a Scalable Application.</p>
<p align="justify">Following are the Scripts that were executed at the Customer site to simulate Exadata Performance and get the Performance Matrix of Application Queries. As mentioned earlier, Exadata Storage Cells provide the intelligence, these scripts use SQL Peformance Analyzer (SPA) to test cell storage in simulation mode and the matrix that is compared is IO_INTERCONNECT_BYTES. This is the amount of data, in bytes, sent by the Storage to the Database Server.</p>
<p align="justify">We start by creating SQL Tuning Sets. Once the STS is created, we need to capture all the Cursors (SQL Queries) in the Cache for a certain period, which is speficied in seconds. In my case, I captured the Queries for 180 Seconds. On a production system, this should be enough as the Shared Pool is usually warm and most of the queries are already found in the cache. If this value is increased, the Analysis (simulation) would take time. Once the Queries are captured, the Simulation is initiated, first with CELL_SIMULATION_ENABLED set to FALSE and then with CELL_SIMULATION_ENABLED set to TRUE. When the simulation is run, the queries are internally executed to generate and capture the io_interconnect_bytes value. Finally, it is time to compare the matrix and generate a TEXT or HTML file.</p>
<pre>
/* Create Tuning SQLSet */

begin
  dbms_sqltune.create_sqlset(
    sqlset_name =&gt; 'Trad_2_Exadata_Simulation',
    description =&gt; 'SQL Tuning Set for Exadata Simulation');
end;
/

/* time_limit is the time in number of seconds the Queries will be captured. */
/* In this case, it is 180 Seconds */
begin
  dbms_sqltune.capture_cursor_cache_sqlset (
    sqlset_name     =&gt; 'Trad_2_Exadata_Simulation',
    time_limit      =&gt; 180,
    repeat_interval =&gt; 10
  );
end;
/

variable Ret_Val clob
set long 999999
begin
  :Ret_Val :=
       dbms_sqlpa.create_analysis_task(
	sqlset_name       =&gt; 'Trad_2_Exadata_Simulation',
	task_name         =&gt; 'Trad_2_Exadata_Simulation_SPA');
end;
/

begin
   dbms_sqlpa.set_analysis_task_parameter ('Trad_2_Exadata_Simulation_SPA','TIME_LIMIT','UNLIMITED');
   dbms_sqlpa.set_analysis_task_parameter ('Trad_2_Exadata_Simulation_SPA','LOCAL_TIME_LIMIT',300);
   :Ret_Val := dbms_sqlpa.execute_analysis_task (
	task_name        =&gt; 'Trad_2_Exadata_Simulation_SPA',
	execution_type   =&gt; 'test execute',
	execution_name   =&gt; 'TRADITIONAL',
	execution_params =&gt; DBMS_ADVISOR.arglist ('cell_simulation_enabled','FALSE'),
	execution_desc   =&gt; 'Exadata simulation disabled'
    );
end;
/

begin
   :Ret_Val := dbms_sqlpa.execute_analysis_task (
	task_name        =&gt; 'Trad_2_Exadata_Simulation_SPA',
	execution_type   =&gt; 'test execute',
	execution_name   =&gt; 'EXADATA',
	execution_params =&gt; dbms_advisor.arglist ('cell_simulation_enabled','TRUE'),
	execution_desc   =&gt; 'Exadata simulation enabled'
    );
end;
/

begin
   :Ret_Val := dbms_sqlpa.execute_analysis_task (
	task_name       =&gt; 'Trad_2_Exadata_Simulation_SPA',
	execution_type  =&gt; 'compare performance',
	execution_params=&gt; dbms_advisor.arglist('comparison_metric','io_interconnect_bytes')
  );
end;
/

set lines 300
set pages 0
set trimspool on
set long 999999
spool report.txt
select dbms_sqlpa.report_analysis_task ('Trad_2_Exadata_Simulation_SPA','TEXT','TYPICAL','ALL') from dual;
spool off
</pre>
<p align="justify">Oracle also provides with a script tcellsim.sql under $ORACLE_HOME/rdbms/admin. This can also be used to run the simulation. The output from the production enviroment is pasted below. I have trimmed the output to make this short.</p>
<pre>
General Information
---------------------------------------------------------------------------------------------

 Task Information:                              Workload Information:

 ---------------------------------------------  ---------------------------------------------
  Task Name    : Trad_2_Exadata_Simulation_SPA   SQL Tuning Set Name        : Trad_2_Exadata_Simulation
  Task Owner   : SYS                             SQL Tuning Set Owner       : SYS
  Description  :                                 Total SQL Statement Count  : 1335

Execution Information:
---------------------------------------------------------------------------------------------
  Execution Name             : EXEC_10626             Started             : 12/30/2010 14:34:36
  Execution Type             : COMPARE PERFORMANCE    Last Updated        : 12/30/2010 14:38:18
  Description                :                        Global Time Limit   : UNLIMITED
  Scope                      : COMPREHENSIVE          Per-SQL Time Limit  : 300

  Status                     : COMPLETED              Number of Errors    : 7

  Number of Timeouts         : 4

  Number of Unsupported SQL  : 77

SQL Details:
-----------------------------
 Object ID            : 3160

 Schema Name          : F_LEA

 SQL ID               : 5um8xff95jn6x

 Execution Frequency  : 266122

 SQL Text             : SELECT 'x' FROM L_AGREEMENT_DTL WHERE AGREEMENTID =

                      :b1 AND STATUS IN ( 'A','L','O','X','C' )

Execution Statistics:
-----------------------------
----------------------------------------------------------------------
|                       | Impact on | Value      | Value    | Impact |
| Stat Name             | Workload  | Before     | After    | on SQL |
----------------------------------------------------------------------
| elapsed_time          |           |  57.165548 |          |        |
| parse_time            |           |    .000424 |          |        |
| cpu_time              |           |      14.94 |          |        |
| user_io_time          |           | 1181.09798 |          |        |
| buffer_gets           |           |    1360874 |          |        |
| cost                  |        0% |          2 |        2 |     0% |
| reads                 |           |     340101 |          |        |
| writes                |           |          0 |          |        |
| io_interconnect_bytes |    84.13% | 2786107392 | 12337536 | 99.56% |
| rows                  |           |          1 |        1 |        |
----------------------------------------------------------------------
SQL Details:
-----------------------------
 Object ID            : 2839

 Schema Name          : F_LEA

 SQL ID               : 1xny80dtnbf6f

 Execution Frequency  : 157981

 SQL Text             : SELECT INSTALTYPE,EMI FROM L_AGREEMENT_DTL WHERE

                      AGREEMENTID = :b1

Execution Statistics:
-----------------------------
---------------------------------------------------------------------
|                       | Impact on | Value     | Value    | Impact |
| Stat Name             | Workload  | Before    | After    | on SQL |
---------------------------------------------------------------------
| elapsed_time          |           |  3.045475 |          |        |
| parse_time            |           |   .000509 |          |        |
| cpu_time              |           |       .65 |          |        |
| user_io_time          |           | 65.463246 |          |        |
| buffer_gets           |           |     57237 |          |        |
| cost                  |        0% |         2 |        2 |     0% |
| reads                 |           |     54172 |          |        |
| writes                |           |         0 |          |        |
| io_interconnect_bytes |     7.77% | 443777024 | 12243136 | 97.24% |
| rows                  |           |         1 |        1 |        |
---------------------------------------------------------------------
</pre>
<p align="justify">From this Simulation, it is clearly visible that the performance benefit using Exadata is tremendous. To make this shoirt, I have pasted only two comparisons, but there were other queries as well that showed a significant amount of performance benefit. In the first query above, the performance benefit on the overall system load is around 85% and the amout of data that traverses between the storage to database server has dropped by 99.56% (from 2.7 GB to 12 MB). This is significant. In the second query as well, since the table is same, the drop is from 443 MB to 12MB, a saving of 97%.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/414/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=414&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2011/01/03/simulating-exadata-storage-performance-over-traditional-storage/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
		<item>
		<title>Oracle Enterprise Manager Grid Control ! A must read Book&#8230;</title>
		<link>http://viveklsharma.wordpress.com/2010/12/20/oracle-enterprise-manager-grid-control-a-must-read-book/</link>
		<comments>http://viveklsharma.wordpress.com/2010/12/20/oracle-enterprise-manager-grid-control-a-must-read-book/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 05:28:05 +0000</pubDate>
		<dc:creator>Vivek</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://viveklsharma.wordpress.com/?p=409</guid>
		<description><![CDATA[My Oracle Colleague, Porus has written a book &#8220;Oracle Enterprise Manager Grid Control: Advanced OEM Techniques for the Real World&#8221; which has recently been published: http://www.rampant-books.com/book_1001_advanced_techniques_oem_grid_control.htm The Book Synopsis is as follows: Oracle’s Enterprise Manager Grid Control is recognized as the IT Industry’s leading Oracle database administration and management tool. It is unrivalled in its [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=409&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">My Oracle Colleague, <a href="http://enterprise-manager.blogspot.com/">Porus</a> has written a book &#8220;Oracle Enterprise Manager Grid Control: Advanced OEM Techniques for the Real World&#8221; which has recently been published: </p>
<p><a href="http://www.rampant-books.com/book_1001_advanced_techniques_oem_grid_control.htm">http://www.rampant-books.com/book_1001_advanced_techniques_oem_grid_control.htm</a></p>
<p>The Book Synopsis is as follows:</p>
<p align="justify">Oracle’s Enterprise Manager Grid Control is recognized as the IT Industry’s leading Oracle database administration and management tool. It is unrivalled in its ability to monitor, manage, maintain and report on entire enterprise grids that comprise hundreds (if not thousands) of Oracle databases and servers following an approach that is consistent and repeatable.</p>
<p align="justify">However, Enterprise Manager Grid Control may seem daunting even to the most advanced Oracle Administrator. The problem is you know about the power of Enterprise Manager but how do you unleash that power amongst what initially appears to be a maze of GUI-based screens that feature a myriad of links to reports and management tasks that in turn lead you to even more reports and management tasks? </p>
<p>This book shows you how to unleash that power.</p>
<p align="justify">Based on the Author’s considerable and practical Oracle database and Enterprise Manager Grid Control experience you will learn through illustrated examples how to create and schedule RMAN backups, generate Data Guard Standbys, clone databases and Oracle Homes and patch databases across hundreds and thousands of databases. You will learn how you can unlock the power of the Enterprise Manager Grid Control Packs, PlugIns and Connectors to simplify your database administration across your company’s database network, as also the management and monitoring of important Service Level Agreements (SLAs), and the nuances of all important real-time change control using Enterprise Manager.</p>
<p align="justify">There are other books on the market that describe how to install and configure Enterprise Manager but until now they haven’t explained using a simple and illustrated approach how to get the most out of your Enterprise Manager. This book does just that.</p>
<p align="justify">This book covers everything on Enterprise Manager Grid Control 11g. I am sure that this book should help you in managing and maintaining a large Enterprise site using Grid Control.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/viveklsharma.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/viveklsharma.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/viveklsharma.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/viveklsharma.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/viveklsharma.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/viveklsharma.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/viveklsharma.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/viveklsharma.wordpress.com/409/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=viveklsharma.wordpress.com&amp;blog=9032851&amp;post=409&amp;subd=viveklsharma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://viveklsharma.wordpress.com/2010/12/20/oracle-enterprise-manager-grid-control-a-must-read-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d21fdb557e46884e8922d65cc08f94a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Vivek</media:title>
		</media:content>
	</item>
	</channel>
</rss>
