Saturday, January 21, 2012

Hotsos Symposium

My favorite conference of the year is just around the corner.

The Hotsos Symposium will be held March 4-8 and will be celebrating its tenth anniversary. I'll be speaking again this year and, as always, am eagerly looking forward to the week. Every year the speakers, topics and opportunities for networking continue to excel and I'm sure this year will be no different. This year's Training Day event will be conducted by Jonathan Lewis so make sure to stay the extra day to take advantage of spending a day with him as he discusses "Designing Optimal SQL".

If you haven't signed up yet, there's still time. I'll look forward to seeing you there!

Wednesday, July 13, 2011

Bug update

We received notice of a patch to correct the bug I discussed with gathering stats on tables with virtual columns/function-based indexes in parallel in my previous post. The patch is number 10013177 and can be found at https://updates.oracle.com/download/10013177.html.

After applying the patch, all stats collections worked without error. Whew!

Thursday, June 30, 2011

Bug alert!

While testing Oracle 11.2.0.2 (on Red Hat Enterprise Linux), I recently bumped up against a problem with stats collections using DEGREE > 1 that results in an ORA-600.

20:56:41 SQL> BEGIN DBMS_STATS.GATHER_TABLE_STATS('TR_OWNER','TR_POL', Estimate_Percent=>dbms_stats.AUTO_SAMPLE_SIZE, method_opt=>'FOR ALL INDEXED COLUMNS SIZE AUTO',cascade=>FALSE, Degree=>dbms_stats.AUTO_DEGREE); END;
20:56:41 2 /
BEGIN DBMS_STATS.GATHER_TABLE_STATS('TR_OWNER','TR_POL', Estimate_Percent=>dbms_stats.AUTO_SAMPLE_SIZE, method_opt=>'FOR ALL INDEXED COLUMNS SIZE AUTO',cascade=>FALSE, Degree=>dbms_stats.AUTO_DEGREE); END;
*
ERROR at line 1:
ORA-20011: Approximate NDV failed: ORA-12801: error signaled in parallel query
server P024, instance db100.srv.com:TRXTPLT2 (2)
ORA-00039: error during periodic action
ORA-00600: internal error code, arguments: [17114], [0x2AE3C33489B8], [], [],
[], [], [], [], [], [], [], []
ORA-06512: at "SYS.DBMS_STATS", line 23112
ORA-06512: at "SYS.DBMS_STATS", line 23205
ORA-06512: at line 1

If I execute with an estimate_percent of anything other than auto_sample_size, the ORA-20011 goes away, but the ORA-600 remains. Interestingly enough, if I execute with Degree=>1, everything is fine.

After doing more research and finding that I could execute a stats collection on other objects without any problems, I narrowed down the problem to the existence of certain types of function-based indexes. In particular, if the table has an index that uses either a DECODE or a CASE expression or a user-defined function, the problem occurs. As long as the table doesn't have one of these, everything works fine.

The contact to Oracle Support in regard to this issue replied as follows:

It possible you're getting the problem described in Bug:11774077 which is closed as a duplicate of Bug:10013177. For more information please read Note:10013177.8. Functional index causes max decode group by sql to truncate values / can cause dump.
Please check if one of the workarounds will solve your problem:
- Set _replace_virtual_columns=false
OR
- Set _disable_function_based_index=true
OR
- Gathering table stats using degree 1.

Ouch! Turning off the use of virtual columns and function-based indexes is *not* an option. We rely quite heavily on them in our application. And, for the tables that have this problem, gathering stats without doing it in parallel (degree 1) is doable, but not desirable as we have a limited window of time to collect stats and have relied on being able to collect in parallel to reduce the total time it takes to complete the collections.

We're still researching other options or workarounds and pushing on Oracle Support for a fix for this problem, but are not making much progress on either front at this point.

I'll update again soon with more information as I have it.

Wednesday, January 26, 2011

Hotsos Symposium 2011

The 2011 Hotsos Symposium begins in just a little over a month (March 6) and I can't wait! I've been fortunate to have attended every Symposium except one (last year) since these events began. When I was asked to conduct the Training Day following this year's main Symposium (the Training Day is on March 10) I was honored to accept and thrilled that I would be back in attendance this year.

I believe the Symposium is unique in many ways. It is the one and only conference that I know of focused specifically on Oracle performance. Over the span of just a few days, attendees are privileged to hear the best speakers from all over the globe. This year's event is overflowing once again with a stellar line-up of presenters on topics such as "Database I/O Performance" (Alex Gorbachev), "Contemporary Latch Internals" (Andrey Nikolaev), and "Five Things Every Programmer (and DBA) Should Know about Oracle" (Andrew Zitelli). Cary Millsap will be delivering his award-winning presentation "Thinking Clearly about Performance" and Kerry Osborne will be delivering the Keynote address as well as presenting on "Tuning Exadata". The week will end up with Tom Kyte's birds-eye view of the week's sessions as he provides his representation of those topics in the insightful and engaging way only Tom can.

I have the privilege of following this great line-up of speakers by presenting the Training Day. My topic (albeit a very wordy title) is "Managing SQL Performance - Practical Information and Tools for Writing and Maintaining Optimally Performing SQL". I'm looking forward to sharing many of the things I do every day that help me to take poorly performing SQL and making it hum! Don't you just love it when you can get a win like reducing a query's response time from nearly an hour down to a few seconds?! I know I do. The thing is, it isn't magic. Admittedly, it's fun to have people shake their heads in wonderment when I'm able to accomplish such "miracles", but I'll share my secrets for how I go about doing it. Well, OK...they're not really secrets. What I do is simply the application of a systematic, repeatable approach that anyone can learn and utilize. Like anything, the more you practice, the better (and faster) you get at the process.

I think one of the most fun things about becoming more and more proficient at optimizing SQL is that you appear to have abilities that seem almost magical. I thought I'd share this video where Penn & Teller demonstrate how what seems like magic can be uncovered and shown to be just well-timed execution of known and practiced actions.



I hope the Training Day will allow me to show you what lurks under the covers and make the magic seem practical for you! See you there!

Monday, October 25, 2010

Left outer join equivalence - Oracle vs ANSI syntax

I was reminded last week while visiting on customer site that it's easy to confuse the syntax you should use if you switch between Oracle's syntax and ANSI syntax for outer joins. Here's an example using the good old standby SCOTT schema to show what I mean. First, I'll show the data from both tables we'll use (emp and dept) so the rest of the examples will be easier to follow.


SCOTT@ORA11R2> select * from emp ;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

14 rows selected.

SCOTT@ORA11R2> select * from dept ;

DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

4 rows selected.


Now, let's join the tables to produce a result set that includes all rows from emp but limits the dept table info to only be included if the deptno = 20.

SCOTT@ORA11R2> select e.empno, e.ename, d.deptno, d.dname
2 from emp e, dept d
3 where e.deptno = d.deptno(+) and d.deptno(+) = 20;

EMPNO ENAME DEPTNO DNAME
---------- ---------- ---------- --------------
7902 FORD 20 RESEARCH
7876 ADAMS 20 RESEARCH
7788 SCOTT 20 RESEARCH
7566 JONES 20 RESEARCH
7369 SMITH 20 RESEARCH
7839 KING
7934 MILLER
7782 CLARK
7900 JAMES
7844 TURNER
7698 BLAKE
7654 MARTIN
7521 WARD
7499 ALLEN

14 rows selected.


Note that we get back the entire set of 14 rows from emp, but only 5 rows have the deptno and dname column values populated. This is because the filter on deptno(+) = 20 is written so that it is applied before the join between emp and dept occurs. Therefore, only rows with deptno = 20 will be joined to their matching emp rows. The remaining rows for employees who are in the other departments will be returned due to the outer join as no rows from dept will be available to match to.

If we wrote the join without including the (+) on the filter, we'd have gotten back only rows for deptno 20 employees as follows:

SCOTT@ORA11R2> select e.empno, e.ename, d.deptno, d.dname
2 from emp e, dept d
3 where e.deptno = d.deptno(+) and d.deptno = 20;

EMPNO ENAME DEPTNO DNAME
---------- ---------- ---------- --------------
7369 SMITH 20 RESEARCH
7566 JONES 20 RESEARCH
7788 SCOTT 20 RESEARCH
7876 ADAMS 20 RESEARCH
7902 FORD 20 RESEARCH

5 rows selected.


However, if we want to return rows only for deptno 20, then we shouldn't use an outer join at all. If the filter is applied after the join, then the rows for other departments will have null values in the deptno and dname columns (as shown earlier) and therefore will not match the filter condition and be eliminated from the result set. You can see that the result is the same if you remove the outer join operator.

SCOTT@ORA11R2> select e.empno, e.ename, d.deptno, d.dname
2 from emp e, dept d
3 where e.deptno = d.deptno
4 and d.deptno = 20;

EMPNO ENAME DEPTNO DNAME
---------- ---------- ---------- --------------
7369 SMITH 20 RESEARCH
7566 JONES 20 RESEARCH
7788 SCOTT 20 RESEARCH
7876 ADAMS 20 RESEARCH
7902 FORD 20 RESEARCH

5 rows selected.


When using ANSI join syntax, you need to make sure to use the filter condition properly as well. With ANSI syntax, the difference is in where you place the condition. In order for the filter to be applied before the join, you must place the filter inside the join condition.

SCOTT@ORA11R2> select e.empno, e.ename, d.deptno, d.dname
2 from emp e left outer join dept d
3 on (e.deptno = d.deptno and d.deptno = 20);

EMPNO ENAME DEPTNO DNAME
---------- ---------- ---------- --------------
7902 FORD 20 RESEARCH
7876 ADAMS 20 RESEARCH
7788 SCOTT 20 RESEARCH
7566 JONES 20 RESEARCH
7369 SMITH 20 RESEARCH
7839 KING
7934 MILLER
7782 CLARK
7900 JAMES
7844 TURNER
7698 BLAKE
7654 MARTIN
7521 WARD
7499 ALLEN

14 rows selected.


If you place the filter in the WHERE clause, the filter is applied after the join.

SCOTT@ORA11R2> select e.empno, e.ename, d.deptno, d.dname
2 from emp e left outer join dept d
3 on (e.deptno = d.deptno)
4 where d.deptno = 20;

EMPNO ENAME DEPTNO DNAME
---------- ---------- ---------- --------------
7369 SMITH 20 RESEARCH
7566 JONES 20 RESEARCH
7788 SCOTT 20 RESEARCH
7876 ADAMS 20 RESEARCH
7902 FORD 20 RESEARCH

5 rows selected.


I tend to use the Oracle syntax most often and am so used to it that when I was shown the ANSI syntax, it took a minute to recall the difference in placement of the filter condition (thanks for the nudge Karl!). It's fairly obvious when looking at a simple example like this as to where the condition belongs, but when you've got a much more complex SQL statement with multiple joins, the effects of placing the filter in the wrong spot may be overlooked.

Hope this little reminder helps!

Friday, October 1, 2010

You know you're a true gadget geek when...

...the power goes off in your home during a major thunder/lightning/rain storm and instead of going to the junk drawer to pull out the flashlight you reach for your iPhone and turn it on so that the soft glow illuminates your surroundings.


I even went so far as to go to the App Store and download a free flashlight app that I then played with until the power came back on. I used my nifty new little app to light my way to the water cooler to refill my water bottle and then returned to the comfort of my couch to play with all the different flashlight choices in the app until the power came back on several minutes later.

Actually it's kinda scary to think that I've crossed some line that makes my iPhone the "go to" solution in almost any situation.

Wednesday, July 21, 2010

Do not feed...

What exactly am I supposed to think when the park near our house has this sign posted in numerous places:

This cracks me up for at least two reasons:
1) because it doesn't say "Beware of alligators" or anything like that, it simply tells you to not feed alligators or other dangerous critters like cats, raccoons and possums, and
2) because there are enough of all of those animals hanging around the park that a warning (and actually a legal ordinance) is needed!

As I was pondering the sign further (while my daughter played in this danger zone), I was thinking that if all these animals happened to be around at the same time, and the alligator looked hungry, I'd grab one of the others and toss it over to the gator, grab my kiddo and run. So, I wonder if it's OK to do that? I mean, since they're all on the sign is it OK for them to eat each other?

Geesh...I think of weird things. Oh well, eat or be eaten I say!