Another SQL Profile to the rescue!

We have had problems with set of databases over the past few weeks. Our team does not support these databases, but my director asked me to help. These are 11.2.0.1 Windows 64 bit Oracle databases running on Windows 2008. The incident reports said that the systems stop working and that the main symptom was that the oracle.exe process uses all the CPU. They were bouncing the database server when they saw this behavior and it took about 30 minutes after the bounce for the CPU to go back down to normal. A Windows server colleague told me that at some point in the past a new version of virus software had apparently caused high CPU from the oracle.exe process.

At first I looked for some known bugs related to high CPU and virus checkers without much success. Then I got the idea of just checking for query performance. After all, a poorly performing query can eat up a lot of CPU. These Windows boxes only have 2 cores so it would not take many concurrently running high CPU queries to max it out. So, I got an AWR report covering the last hour of a recent incident. This was the top SQL:

Top SQL

The top query, sql id 27d8x8p6139y6, stood out as very inefficient and all CPU. It seemed clear to me from this listing that the 2 core box had a heavy load and a lot of waiting for CPU queuing. %IO was zero but %CPU was only 31%. Most likely the rest was CPU queue time.

I also looked at my sqlstat report to see which plans 27d8x8p6139y6 had used over time.

PLAN_HASH_VALUE END_INTERVAL_TIME     EXECUTIONS Elapsed ms
--------------- --------------------- ---------- -----------
     3067874494 07-MAR-16 09.00.50 PM        287  948.102286
     3067874494 07-MAR-16 10.00.03 PM        292  1021.68191
     3067874494 07-MAR-16 11.00.18 PM        244  1214.96161
     3067874494 08-MAR-16 12.00.32 AM        276  1306.16222
     3067874494 08-MAR-16 01.00.45 AM        183  1491.31307
      467860697 08-MAR-16 01.00.45 AM        125      .31948
      467860697 08-MAR-16 02.00.59 AM        285  .234073684
      467860697 08-MAR-16 03.00.12 AM        279  .214354839
      467860697 08-MAR-16 04.00.25 AM        246   .17147561
      467860697 08-MAR-16 05.00.39 AM         18        .192
     2868766721 13-MAR-16 06.00.55 PM         89    159259.9
     3067874494 13-MAR-16 06.00.55 PM          8  854.384125
     2868766721 13-MAR-16 07.00.50 PM         70  1331837.56

Plan 2868766721 seemed terrible but plan 467860697 seemed great.

Our group doesn’t support these databases so I am not going to dig into how the application gathers statistics, what indexes it uses, or how the vendor designed the application. But, it seems possible that forcing the good plan with a SQL Profile could resolve this issue without having any access to the application or understanding of its design.

But, before plunging headlong into the use of a SQL Profile I looked at the plan and the SQL text.  I have edited these to hide any proprietary details:

SELECT T.*
    FROM TAB_MYTABLE1 T,
         TAB_MYTABLELNG A,
         TAB_MYTABLE1 PIR_T,
         TAB_MYTABLELNG PIR_A
   WHERE     A.MYTABLELNG_ID = T.MYTABLELNG_ID
         AND A.ASSIGNED_TO = :B1
         AND A.ACTIVE_FL = 1
         AND T.COMPLETE_FL = 0
         AND T.SHORTED_FL = 0
         AND PIR_T.MYTABLE1_ID = T.PIR_MYTABLE1_ID
         AND ((PIR_A.FLOATING_PIR_FL = 1 
               AND PIR_T.COMPLETE_FL = 1)
              OR PIR_T.QTY_PICKED IS NOT NULL)
         AND PIR_A.MYTABLELNG_ID = PIR_T.MYTABLELNG_ID
         AND PIR_A.ASSIGNED_TO IS NULL
ORDER BY T.MYTABLE1_ID

The key thing I noticed is that there was only one bind variable. The innermost part of the good plan uses an index on the column that the query equates with the bind variable. The rest of the plan is a nice nested loops plan with range and unique index scans. I see plans in this format in OLTP queries where you are looking up small numbers of rows using an index and join to related tables.

-----------------------------------------------------------------
Id | Operation                        | Name                     
-----------------------------------------------------------------
 0 | SELECT STATEMENT                 |                          
 1 |  SORT ORDER BY                   |                          
 2 |   NESTED LOOPS                   |                          
 3 |    NESTED LOOPS                  |                          
 4 |     NESTED LOOPS                 |                          
 5 |      NESTED LOOPS                |                          
 6 |       TABLE ACCESS BY INDEX ROWID| TAB_MYTABLELNG           
 7 |        INDEX RANGE SCAN          | AK_MYTABLELNG_BY_USER    
 8 |       TABLE ACCESS BY INDEX ROWID| TAB_MYTABLE1             
 9 |        INDEX RANGE SCAN          | AK_MYTABLE1_BY_MYTABLELNG
10 |      TABLE ACCESS BY INDEX ROWID | TAB_MYTABLE1             
11 |       INDEX UNIQUE SCAN          | PK_MYTABLE1              
12 |     INDEX UNIQUE SCAN            | PK_MYTABLELNG            
13 |    TABLE ACCESS BY INDEX ROWID   | TAB_MYTABLELNG           
-----------------------------------------------------------------

The bad plan had a gross Cartesian merge join:

Plan hash value: 2868766721

----------------------------------------------------------------
Id | Operation                       | Name                     
----------------------------------------------------------------
 0 | SELECT STATEMENT                |                          
 1 |  NESTED LOOPS                   |                          
 2 |   NESTED LOOPS                  |                          
 3 |    MERGE JOIN CARTESIAN         |                          
 4 |     TABLE ACCESS BY INDEX ROWID | TAB_MYTABLE1             
 5 |      INDEX FULL SCAN            | PK_MYTABLE1              
 6 |     BUFFER SORT                 |                          
 7 |      TABLE ACCESS BY INDEX ROWID| TAB_MYTABLELNG           
 8 |       INDEX RANGE SCAN          | AK_MYTABLELNG_BY_USER    
 9 |    TABLE ACCESS BY INDEX ROWID  | TAB_MYTABLE1             
10 |     INDEX RANGE SCAN            | AK_MYTABLE1_BY_MYTABLELNG
11 |   TABLE ACCESS BY INDEX ROWID   | TAB_MYTABLELNG           
12 |    INDEX RANGE SCAN             | AK_MYTABLELNG_BY_USER    
----------------------------------------------------------------

Reviewing the SQL made me believe that there was a good chance that a SQL Profile forcing the good plan would resolve the issue. Sure, there could be some weird combination of data and bind variable values that make the bad plan the better one. But, given that this was a simple transactional application it seems most likely that the straightforward nested loops with index on the only bind variable plan would be best.

We used the SQL Profile to force these plans on four servers and so far the SQL Profile has resolved the issues. I’m not saying that forcing a plan using a SQL Profile is the only or even best way to resolve query performance issues. But, this was a good example of where a SQL Profile makes sense. If modifying the application, statistics, parameters, and schema is not possible then a SQL Profile can come to your rescue in a heartbeat.

Bobby

Posted in Uncategorized | Leave a comment

Math Resources

I feel like I have not been posting very much on this blog lately. I have been focused on things outside of Oracle performance so I haven’t had a lot of new scripts to post.  I have been quietly updating my Python source code on GitHub so check that out. I have spent a lot of time educating myself in various ways including through the leadership and communication training program that comes from Toastmasters. My new job title is “Technical Architect” which is a form of technical leadership so I’m trying to expand myself beyond being an Oracle database administrator that specializes in performance tuning.

In addition to developing my leadership and communication skills I have gotten into a general computer science self-education kick. I took two introductory C.S. classes on edX. I also read a book on Linux hacking and a book on computer history. I was thinking of buying one of the Donald Knuth books or going through MIT’s free online algorithms class class 6.006. I have a computer science degree and spent two years in C.S. graduate school but that was a long time ago. It is kind of fun to refresh my memory and catch up with the latest trends. But the catch is that both the Knuth book and MIT’s 6.006 class require math that I either never learned or have forgotten. So, I am working my way through some math resources that I wanted to share with those who read this blog.

The first thing I did was to buy a computer math book, called Concrete Mathematics,  that seemed to cover the needed material. Reviews on Amazon.com recommended this book as good background for the Knuth series and one of the Oracle performance experts that I follow on Twitter recommended it for similar reasons. But, after finishing my second edX class I began exploring the MIT OCW math class that was a prerequisite to MIT’s 6.006 algorithms class. MIT calls the math class 6.042J and I am working through the Fall 2010 version of the class. There is a lot of overlap between the class and the book but they are not a perfect match. The book has some more difficult to follow material than the class. It is probably more advanced.  The class covers some topics, namely graph theory, that the book does not.  The free online class has some very good lecture videos by a top MIT professorTom Leighton. I even had my wife and daughters sit down and watch his first lecture with me on our family television for fun on my birthday.

The book led me to a great free math resource called Maxima. Maxima has all kinds of great math built into it such as solving equations, factoring integers, etc. Plus, it is free. There are other similar and I think more popular programs that are not free but for my use it was great to simply download Maxima and have its functionality at my fingertips.

The last resource that I wanted to mention is the Mathematics section of Stack Exchange. It is a pretty structured online forum with a question and answer format. It is helpful to me since I am going through 6.042J without a professor or teaching assistant to answer my questions. The people on math stack exchange are very helpful if you at least try to follow the etiquette for their forum. For example, they have an easy to use way to format math formulas in your questions and answers and the users of the forum expect you to use it. But it isn’t hard. I had one question from the Concrete Math book where I couldn’t understand the answer key in the back. I asked about it on stack exchange and got a great answer in no time.

Anyway, maybe all of this math and computer science study is a departure from my bread and butter Oracle database work and performance tuning. But the free online resources like the OCW web site, the Maxima program, and the stack exchange forum along with the book that I paid for are a great set of resources. I have already used some of the concepts that I have learned about number theory and its application to RSA encryption. But, at the same time I am enjoying studying these things and mostly see it as something fun to do in my spare time. (I’m weird I know.)

So, I have written this blog post to share the math related things that I am studying and using to those who might benefit from them. I am not a math expert, but I am getting a lot out of these materials. I hope that others find these resources as enjoyable and educational as I have.

Bobby

Posted in Uncategorized | 3 Comments

General troubleshooting lessons from recent Delphix issue

Delphix support helped me resolve an issue yesterday and the experience gave me the idea of writing this post about several general computer issue troubleshooting tips that I have learned down through the years. Never mind that I ignored these lessons during this particular problem. This is more of a “do as I say” and not a “do as I do” story.  Actually, some times I remember these lessons. I didn’t do so well this week. But the several mistakes that I made resolving this recent Delphix issue motivate me to write this post and if nothing else remind myself of the lessons I’ve learned in the past about how to resolve a computer problem.

Don’t panic!

I’m reminded of the friendly advice on the cover of the Hitchhiker’s Guide to the Galaxy: “Don’t panic!”. So, yesterday it was 4:30 pm. I had rebooted the Delphix virtual machine and then in a panic had the Unix team reboot the HP Unix target server. But, still I could not bring up any of the Delphix VDBs.  We had people coming over to our house for dinner that night and I was starting to worry that I would be working on this issue all night. I ended up getting out of the office by 5:30 pm and had a great dinner with friends. What was I so stressed about? Even the times that I have been up all night it didn’t kill me. Usually the all night issues lead to me learning things anyway.

Trust support

The primary mistake that I made was to get my mind fixed on a solution to the problem instead of working with Delphix support and trusting them to guide us to the solution. We had a number of system issues due to a recent network issue and I got my mind set on the idea that my Delphix issue was due to some network hangup. I feel sorry for our network team because it seems like the first thought people have any time there is some issue is that it is a “network issue”. I should know better. How many times have I been working on issues when everyone says it is a “database issue” and I’m annoyed because I know that the issue is somewhere else and they are not believing me when I point to things outside the database. Anyway, I opened a case with Delphix on Monday when I couldn’t get a VDB to come down. It just hung for 5 minutes until it gave me an error. I assumed that it was a network hangup and got fixated on rebooting the Delphix VM. Ack! Ultimately, I ended up working with two helpful and capable people in Delphix support and they resolved the issue which was not what I thought at all. There are times to disagree with support and push for your own solution but I did this too early in this case and I was dead wrong.

Keep it simple

I’ve heard people refer to Occam’s razor which I translate in computer terms to mean “look for simple problems first”. Instead of fixing my mind on some vague network issue where the hardware is not working properly, how about assuming that all the hardware and software is working normally and then thinking about what problems might cause my symptoms? I can’t remember how many times this has bit me. There is almost always some simple explanation.  In this case I had made a change to a Unix shell script that runs when someone logs in as the oracle user. This caused Delphix to no longer be able to do anything with the VDBs on that server. Oops! It was a simple blunder, no big deal. But I’m kicking myself for not first thinking about a simple problem like a script change instead of focusing on something more exotic.

What changed?

I found myself saying the same dumb thing that I’ve heard people say to me all the time: nothing changed. In this case I said something like “this has worked fine for 3 years now and nothing has changed”. The long-suffering and patient Delphix support folks never called me on this, but I was dead wrong. Something had to have changed for something that was working to stop working. I should have spent time looking at the various parts of our Delphix setup to see if anything had changed before I contacted support. All I had to do was see the timestamp on our login script and I would see that something had recently changed.

Understand how it all works

I think my Delphix skills are a little rusty. We just started a new expansion project to add new database sources to Delphix. It has been a couple of years since I’ve done any heavy configuration and trouble shooting. But I used to have a better feel for how all the pieces fit together. I should have thought about what must have gone on behind the scenes when I asked Delphix to stop a VDB and it hung for 5 minutes. What steps was it doing? Where in the process could the breakdown be occurring? Delphix support did follow this type of reasoning to find the issue. They manually tried some of the steps that the Delphix software would do automatically until they found the problem. If I stopped to think about the pieces of the process I could have done the same. This has been a powerful approach to solving problems all through my career. I think about resolving PeopleSoft issues. It just helps to understand how things work. For example, if you understand how the PeopleSoft login process works you can debug login issues by checking each step of the process for possible issues. The same is true for Oracle logins from clients. In general, the more you understand all the pieces of a computer system, down to the transistors on the chips, the better chance you have of visualizing where the problem might be.

Well, I can’t think of any other pearls of wisdom from this experience but I thought I would write these down while it was on my mind. Plus, I go on call Monday morning so I need to keep these in mind as I resolve any upcoming issues. Thanks to Delphix support for their good work on this issue.

Posted in Uncategorized | Leave a comment

Cloning 10.2.0.3 Oracle Home on fully patched 11.31 HP-UX hangs

I based this blog post on information that I learned from this Oracle Support document:

Runinstaller And Emctl Do Not Work After Upgrading HP-UX 11.31 To 11.31 Update3 (Sep 2008) (Doc ID 780102.1)

My situation was slightly different from what Oracle’s note describes so I thought it would be helpful to document what I found.

In my case I am cloning an Oracle 10.2.0.3 home on to a fully patched HP-UX 11.31 server. I have used this same clone process on Oracle 11.1, 11.2, and 12.1 Oracle Homes with no issues. The symptom is that the 10.2 clone process just hangs with no helpful messages.

I searched Oracle’s support site and the web for issues with 10.2 cloning and could not find anything that matched my symptoms. I then decided to give up on cloning and try to install the base 10.2.0.1 binaries and then patch to match the home that I was trying to clone. The 10.2.0.1 install also hung.  But, I know that the 10.2.0.1 install works since we have used it on many other similar systems. But, they were on HP-UX 11.23 and not the fully patched HP-UX 11.31. So, I searched for installer issues on 11.31 and 10.2 and found the Oracle document listed above.

Evidently there is some bug with the JDK that Oracle included in 10.2 so that it does not work with HP-UX 11.31 with the current patches. A later version of Java resolves the issue.

Now that I understood the issue I decided to go back to the clone and try to apply the recommendations from the Oracle note, even though it doesn’t mention cloning.

The Oracle note suggests adding the –jreLoc /opt/java1.4 option to the runInstaller command line. The only catch is that my HP system did not have /opt/java1.4.  The oldest java we have installed is in /opt/java1.5. So, I tried the clone with the -jreLoc /opt/java1.5 option and it got almost to the end of the clone before it hung doing some emctl step.  Then I realized that I needed to follow the steps in the Oracle note to rename the Oracle Home’s jdk directory and set up a link to the Java1.5 directory.  So, I did these steps to point to the correct jdk directory:

cd $ORACLE_HOME

mv jdk jdk.orig

ln -s /opt/java1.5 jdk

Then I ran the clone with this command line:

$ORACLE_HOME/oui/bin/runInstaller -jreLoc /opt/java1.5 -clone -silent ORACLE_HOME=$ORACLE_HOME ORACLE_BASE=$ORACLE_BASE ORACLE_HOME_NAME=$ORACLE_HOME_NAME

Success!

It wasn’t that hard to apply the note to the clone situation but I thought it was worth blogging it. If someone googles runInstaller clone hang 10.2 11.31 and needs the solution they will find it.

Of course, I may be the only person in the world cloning a 10.2 Oracle Home on an HP-UX Itanium 11.31 system, but it’s here if someone needs it.

Bobby

Posted in Uncategorized | Leave a comment

Another python graph – one wait event

Here is another graph that I created in Python with Pyplot:

onewait_medium

This is onewait.py in my PythonDBAGraphs repository. myplot.py has the plotting code.  db.py has the database access code.

I blanked out the database name in the example graph to hide it.

This is a graphical version of my onewaitevent.sql script. It queries the AWR looking at a particular wait event per hour. You look at the number of wait events in an hour to see how busy the system was and then the average elapsed time for that hour. Also, you set the smallest number of waits to include so you can drop hours where nothing is going on.

In the example graph you can find times where the average time for a db file sequential read is high and the system is busy. You use the top graph to see how busy the system is and the bottom to see where the average time spikes.

Still just an experiment but I thought I would pass it along. It isn’t that hard to create the graph in Python and I seem to have a lot of flexibility since I’m writing code instead of using an existing program like Excel.

Bobby

P.S.

4/26/2021

Updated the links to point to the current version of the same code.

Posted in Uncategorized | 3 Comments

Trying Python and Pyplot for Database Performance Graphs

In the past I have used Excel to graph things related to Oracle database performance. I am trying out Python and the Pyplot library as an alternative to Excel.  I took a graph that I had done in Excel and rewrote it in Python. The graph shows the CPU usage within the database by category.  For example, I labeled the database CPU used by a group of web servers “WEBFARM1” on the graph.

Here is an example graph:

monday

You can find most of this code in the Python section of my GitHub repository. Here is the code that I used to create the example graph above using some made up data: zip

To make this graph in Excel I was running a sqlplus script and cutting and pasting the output into a text file that I imported into Excel. Very manual. No doubt there are ways that I could have automated what I was doing in Excel. But I have studied Python as part of the edX classes I took so I thought I would give it a try.

Python let me write a program to run the graph from an icon on my desktop. I used the cx_Oracle package to pull the data from the database and Pyplot for the graph.

I’m running the Windows 32 bit version of Canopy Express for my Python development environment. This environment comes with Pylot so I just had to install cx_Oracle to have all the packages I needed to make the graph.

I think both Excel and Python/Pyplot still have value. Excel still seems easier for quick and dirty graphing. But I used Python to automate a report that I run every day with fewer manual steps.  Probably could have done the same thing in Excel but I have recently studied Python so I was able to apply what I learned in my classes without a lot more effort.

Bobby

Posted in Uncategorized | 4 Comments

Github Repository

I am experimenting with Github. I have created a repository for my Oracle database related scripts. Here is my Github URL: https://github.com/bobbydurrett/PythonDBAGraphs

You can clone this repository locally if you have git installed using this command:

git clone https://github.com/bobbydurrett/PythonDBAGraphs

I’ve had challenges before when I write a blog post about a script and then revise the script later.  It seems weird to update the post with links to the new version.  So, I’m thinking of using github to expose the scripts that I want to share with the Oracle community and then I can update them over time and the version history will be visible.

Let me know if you have any questions or suggestions.  This is just my first attempt at using Github for this purpose.

Bobby

p.s. I’m updating this. I’m just keeping my Python scripts here for now.

Posted in Uncategorized | Leave a comment

Update hinted for wrong index

I worked with our support team to improve the performance of a PeopleSoft Financials update statement yesterday. The update statement had an index hint already in it but the index was not the best one of the available indexes.

Here is the original update statement:

UPDATE /*+ INDEX(B PSCPYMNT_VCHR_XREF) */
 PS_PYMNT_VCHR_XREF B
 SET BANK_SETID = :1,
 BANK_CD = :2,
 BANK_ACCT_KEY = :3,
 PYMNT_METHOD = :4,
 BANK_ACCT_SEQ_NBR = :5,
 EFT_LAYOUT_CD = :6,
 STL_THROUGH = :7
 WHERE B.REMIT_SETID = 'XYZ'
 AND B.REMIT_VENDOR = :8
 AND B.PYMNT_SELCT_STATUS = 'N'
 AND B.PYMNT_ID = ' '
 AND B.BANK_ACCT_KEY NOT LIKE ('EXP%')

I listed out the columns for the indexes on the table using the “querytuning” part of my standard sql tuning scripts. (current version)

Here are the columns for the hinted index:

REMIT_SETID
REMIT_VENDOR
VNDR_LOC

The where clause includes only the first two columns.

But another similar index, PSEPYMNT_VCHR_XREF, exists with these columns:

REMIT_SETID
REMIT_VENDOR
PYMNT_SELCT_STATUS

The where clause has all three of these columns. So, why was the original query hinted this way? Does the E index not work better than the C index? I ran this query to see how selective the condition PYMNT_SELCT_STATUS = ‘N’ is.

>select PYMNT_SELCT_STATUS,count(*)
 2 from PS_PYMNT_VCHR_XREF B
 3 WHERE B.REMIT_SETID = 'XYZ'
 4 AND B.REMIT_VENDOR = '12345678'
 5 group by PYMNT_SELCT_STATUS;

P COUNT(*)
- ----------
C 5
N 979
P 177343
X 5485

I included the conditions on the first two columns that both indexes share, but removed the other conditions from the original update. A count on the number of rows that meet the conditions of only these two columns shows how many rows the original index will have to use to check the remaining where clause conditions.

I grouped by PYMNT_SELCT_STATUS to see how many rows met the condition PYMNT_SELCT_STATUS = ‘N’ and how many did not. Grouping on PYMNT_SELCT_STATUS shows how many rows the new index will use to check the remaining conditions in the where clause. I ran this query to see if the second index would use fewer rows than the first.

This query showed that only 979 of the over 180,000 rows met the condition. This made me think that the E index which includes PYMNT_SELCT_STATUS has a good chance of speeding up the original update. I ran a count with a hint forcing the C index and then again forcing the E index:

>
>set timing on
>
>select /*+ INDEX(B PSCPYMNT_VCHR_XREF) */ count(*)
 2 from PS_PYMNT_VCHR_XREF B
 3 WHERE B.REMIT_SETID = 'XYZ'
 4 AND B.REMIT_VENDOR = '12345678'
 5 AND B.PYMNT_SELCT_STATUS = 'N'
 6 AND B.PYMNT_ID = ' '
 7 AND B.BANK_ACCT_KEY NOT LIKE ('EXP%');

 COUNT(*)
----------
 982

Elapsed: 00:13:52.53
>
>select /*+ INDEX(B PSEPYMNT_VCHR_XREF) */ count(*)
 2 from PS_PYMNT_VCHR_XREF B
 3 WHERE B.REMIT_SETID = 'XYZ'
 4 AND B.REMIT_VENDOR = '12345678'
 5 AND B.PYMNT_SELCT_STATUS = 'N'
 6 AND B.PYMNT_ID = ' '
 7 AND B.BANK_ACCT_KEY NOT LIKE ('EXP%');

 COUNT(*)
----------
 982

Elapsed: 00:00:01.28

The original hint caused the select count(*) query to run in 13 minutes while the new hint caused it to run in 1 second. Clearly the new E index causes the query to run faster!

The developer that I was working with found the problem update statement in some PeopleCode and was able to edit the hint forcing it to use the better index. We migrated the modified code to production and the user was able to run the update statement without the web site timing out. Prior to the change the user was not able to complete the update because the SQL statement took so long it exceeded our application server timeout.

Bobby

 

Posted in Uncategorized | Leave a comment

Tested 1000 Select Statements on New Exadata X5

I finished testing 1000 select statements on our new Exadata X5 to see if they would run faster or slower than on our older Exadata V2.  Our current production V2 has 12 nodes and the new X5 has only 2.  The memory and parallel server parameters on the X5 are 6 times are large as on the old one, since we have one sixth as many hosts and more than 6 times the memory and CPU per host. I think that memory parameters can sometimes change execution plans, and of course with the newer Exadata software who knows what other differences we might see.  I wanted to see if any plan changes or other issues caused some queries to run much slower on our newer Exadata system than the old one. I picked 1000 select statements at random from our current production and tested them comparing plans and execution time. In the end I did not find any bad plan changes and on average the tested select statements ran about 4 times faster on the X5 than on the older V2.

I used my testselect package that I have mentioned in several other posts. Here are some other examples of using this package for performance tuning:

https://www.bobbydurrettdba.com/2015/03/02/different-plan_hash_value-same-plan/

https://www.bobbydurrettdba.com/2013/12/09/testing-removing-subpartitions-from-a-table-with-query-testing-package/

In the other posts I was using the package to test the effect of some change on query plans and performance.  So, I was comparing two different situations on the same host. But, in this case I was comparing two different hosts with essentially the same data and settings. But they had different versions of Exadata hardware and larger parameters and fewer nodes on the newer host.  Here are the results of my first run with all 1000 statements.  I got the execution plan for all 1000 select statements but only executed the ones with different plans.  Here were the results:

>execute TEST_SELECT.display_results('X5','V2');
        
Select statements that ran 3 times faster with X5 than with V2.
        
T1=X5
T2=V2
        
        SQLNUMBER T1_EXECUTE_PLAN_HASH T2_EXECUTE_PLAN_HASH T1_ELAPSED_IN_SECONDS T2_ELAPSED_IN_SECONDS
        --------- -------------------- -------------------- --------------------- ---------------------
                3            287237826            287237826                     3                    34
                4           1245040971           1245040971                     1                    11
                9             36705296           2770058206                     4                    22

... edited out most of the lines for brevity ...

              997           2423577330           2423577330                     0                     9
              998           2217180459           3921538090                     1                    13
             1000           3842377551           1690646521                     2                    12
        
Number of selects=329
        
Select statements that ran 3 times faster with V2 than with X5.
        
T1=V2
T2=X5
        
        SQLNUMBER T1_EXECUTE_PLAN_HASH T2_EXECUTE_PLAN_HASH T1_ELAPSED_IN_SECONDS T2_ELAPSED_IN_SECONDS
        --------- -------------------- -------------------- --------------------- ---------------------
               95           3919277442           3919277442                     0                     2
              210           3508255766           3508255766                     0                     2
              282           3946849555           3085057493                     0                     6
              347           3278587008            789099618                    19                   170
              375            581067860            460184496                     0                     3
              429            534521834            534521834                     1                     6
              569           3953904703           3484839332                     0                     2
              681            946688683           3451337204                     1                     6
              697            908111030           2971368043                     0                     1
              699           3756954097           1915145267                     0                     1
              706           1121196591           1121196591                     0                     2
              708            581067860            460184496                     0                     4
              797            908111030           2841065272                     0                     5
              950            786005624           2571241212                    45                   460
              966           3151548044           3151548044                     1                     5
        
Number of selects=15
        
Summary of test results
        
                   TEST_NAME TOTAL_ELAPSED_IN_SECONDS SELECTS_EXECUTED AVERAGE_ELAPSED_IN_SECONDS
        -------------------- ------------------------ ---------------- --------------------------
                          X5 5545.9999999999999999999              486                         11
                          V2                    21138              486                         43

Of the tested statements 329 ran 3 or more times faster on the X5.  But 15 selects ran 3 or more times faster on the old V2.  So, I needed to test the 15 selects again on both servers.

I’m not sure if it was smart or not, but I decided to run all the selects 5 times in a row to maximize caching.  The X5 is new and not in use so there wouldn’t be any activity to stimulate caching.  My test script for the X5 looked like this:

truncate table test_results;

execute TEST_SELECT.execute_all('X5');
execute TEST_SELECT.execute_all('X5');
execute TEST_SELECT.execute_all('X5');
execute TEST_SELECT.execute_all('X5');
execute TEST_SELECT.execute_all('X5');
execute TEST_SELECT.reexecute_errored('X5');
execute TEST_SELECT.reexecute_errored('X5');
execute TEST_SELECT.reexecute_errored('X5');
execute TEST_SELECT.reexecute_errored('X5');
execute TEST_SELECT.reexecute_errored('X5');

After we made sure that the system had cached everything, all 15 selects ran, on average, 4 times faster on the X5 than the V2:

TE  SQLNUMBER SQL_ID        EXPLAIN_PLAN_HASH EXECUTE_PLAN_HASH ROWS_FETCHED ELAPSED_IN_SECONDS CPU_USED_BY_THIS_SESSION CONSISTENT_GETS DB_BLOCK_GETS PARSE_TIME_ELAPSED PHYSICAL_READS ERROR_MESSAGE
-- ---------- ------------- ----------------- ----------------- ------------ ------------------ ------------------------ --------------- ------------- ------------------ -------------- ----------------------------------------------------------------
X5         95 54a8k0yhbgyfq                          3919277442            1                  0                       12            2583            14                  0              1
V2         95 54a8k0yhbgyfq                          3919277442            1                  1                       15            2583            14                  1              1
V2        210 b132ygmp743h4                          3508255766            0                  2                       19            1592            14                  0              1
X5        210 b132ygmp743h4                          3508255766            0                  2                        8            1430            14                  0              1
V2        282 aw5f12xsa8c2h                          3946849555            0                  0                       14            3468            14                  0              2
X5        282 aw5f12xsa8c2h                          3946849555            0                  0                        8            3322            14                  2              2
V2        347 8ncbyjttnq0sk                          3278587008            1                  3                      462         1203794            14                  0          61838
X5        347 8ncbyjttnq0sk                          3278587008            1                  2                      206         1126539            14                  4          51849
X5        375 4yq5jkmz2khv5                           581067860            0                  0                        9           14530            14                  0              2
V2        375 4yq5jkmz2khv5                           581067860            0                  0                       19           14686            14                  1              2
V2        429 49pyzgr4swm4p                           534521834            0                  2                       11            1814            14                  0              0
X5        429 49pyzgr4swm4p                           534521834            0                  0                        5            1638            14                  1              0
X5        569 3afmdkmzx6fw8                           630418386          694                  0                       74           70173            14                  3              0
V2        569 3afmdkmzx6fw8                          3527323087          694                  1                       73           68349            14                  0           3588
V2        681 dyufm9tukaqbz                           668513927            0                  0                       10            6298            14                  0              2
X5        681 dyufm9tukaqbz                          3317934314            0                  0                        8            6096            14                  0              2
V2        697 1fqc3xkzw8bhk                           908111030            0                  0                        3            1406            14                  0              1
X5        697 1fqc3xkzw8bhk                           908111030            0                  0                        2            1406            14                  0              1
V2        699 03qk2cjgr4q2k                          1915145267           31                  0                      476           95922            14                  1              0
X5        699 03qk2cjgr4q2k                          1915145267           31                  0                      272           96299            14                  0              0
V2        706 28fnjtdhjqwrg                          1121196591            0                  0                       21            1355            14                  0              4
X5        706 28fnjtdhjqwrg                          1121196591            0                  0                       13            1355            14                  0              4
V2        708 2yrkwqs46nju0                           581067860            0                  0                       14           14684            14                  0              0
X5        708 2yrkwqs46nju0                           581067860            0                  0                        9           14528            14                  0              0
V2        797 dc5481yn8pm85                           908111030            0                  0                        3            1407            14                  0              2
X5        797 dc5481yn8pm85                           908111030            0                  0                        2            1407            14                  0              2
V2        950 by6n1m74j82rt                           786005624            6                  7                     2087          249736            14                  1         245443
X5        950 by6n1m74j82rt                          2571241212            6                  0                      186           90897            14                  0              3
X5        966 5c2n74gfrxwxx                          3151548044           12                  0                       24          116360            14                  9          84949
V2        966 5c2n74gfrxwxx                          3151548044           12                  0                       52          119701            14                  1          88002

The summary of the results:

Select statements that ran 3 times faster with X5 than with V2.
	
T1=X5
T2=V2
	
	SQLNUMBER T1_EXECUTE_PLAN_HASH T2_EXECUTE_PLAN_HASH T1_ELAPSED_IN_SECONDS T2_ELAPSED_IN_SECONDS
	--------- -------------------- -------------------- --------------------- ---------------------
	       95           3919277442           3919277442                     0                     1
	      429            534521834            534521834                     0                     2
	      569            630418386           3527323087                     0                     1
	      950           2571241212            786005624                     0                     7
	
Number of selects=4
	
Select statements that ran 3 times faster with V2 than with X5.
	
T1=V2
T2=X5
	
	SQLNUMBER T1_EXECUTE_PLAN_HASH T2_EXECUTE_PLAN_HASH T1_ELAPSED_IN_SECONDS T2_ELAPSED_IN_SECONDS
	--------- -------------------- -------------------- --------------------- ---------------------
	
Number of selects=0
	
Summary of test results
	
	           TEST_NAME TOTAL_ELAPSED_IN_SECONDS SELECTS_EXECUTED AVERAGE_ELAPSED_IN_SECONDS
	-------------------- ------------------------ ---------------- --------------------------
	                  X5                        4               15                          0
	                  V2                       16               15                          1

I guess it is no surprise that the X5 is faster than the five-year older V2.  But, I thought it was a good example of how to use my testselect package to do see how a set of queries will run in two different situations.

Bobby

Posted in Uncategorized | Leave a comment

OakTable video of myself and others

You can find the full length video of my Delphix talk that I did at OakTable World on Tuesday here: url

Also, the OakTable folks have updated the OakTable World agenda page with video of all the talks. This has lots of good material and for free. Scroll down to the bottom of the page to find the links to the videos.

Bobby

Posted in Uncategorized | Leave a comment