Hello, you are not logged in.  Login or sign up
Toad on Twitter Follow Toad Search Toad World Search
Blogger List   

All Recent Blog Entries
 

Johannes Ahrends
Unicode and Toad

Ben Boise
Toad SC Discussions

Kevin Dalton
Benchmark Factory

Steven Feuerstein
PL/SQL Obsession

Devin Gallagher
Toad SC discussions

Stuart Hodgins
JProbe Discussions

  Henrik "Mauritz" Johnson
Toad Tips & Tricks on the "other" Toads
  Mark Kurtz
Toad SC discussions
  Michael Lumbard
Toad SC discussions
Daniel Norwood
Toad for Data Analysts,
Toad Extension for Visual Studio
Debbie Peabody
Toad for Data Analysts
Gary Piper
Toad Reports Manager
John Pocknell
Toad for Oracle, JProbe
Kuljit Sangha
Toad SC discussions
Bert Scalzo Indicates Oracle ACE status
Toad for Oracle, Data Modeling, Benchmarking
Jeff Smith
Toad product family
Richard To
SQL Optimization
Jim Wankowski
DB2 - LUW and z/OS
John Weathington
  Toad World Editor
Toad World issues

  Toad Data Modeler Opens in a new window
Data Modeling
 
  Real Automated Code Testing for Oracle
Quest Code Tester blog

Blogs
Toad and Database Commentaries

Toad World blogs are a mix of insightful how-tos from Quest experts as well as their commentary on experiences with new database technologies.  Have some views of your own to share?  Post your comments!  Note:  Comments are restricted to registered Toad World users.

Do you have a topic that you'd like discussed?  We'd love to hear from you.  Send us your idea for a blog topic.

A SQL that returns records faster is not necessarily better-10 Common Misconceptions in SQL Tuning #4
 
Location: Blogs Richard To's Blog    
 RichardTo Friday, August 14, 2009 5:52 AM

This blog is the fourth in a series about misconceptions surrounding SQL tuning that are quite common. It covers the misconception that the goal of SQL tuning is only to make a SQL return all the records faster.

I still remember around 20 years ago, I was using SQL*Plus to tune my SQL statements. At that time, it was my impression that a good SQL rewrite was one that normally would return the records faster.  No SQL tuning tools were available in the market at that time, so SQL*Plus was the only product I could use to tune my SQL statements. Sometimes I had to use my watch to keep track of the speed of each rewritten SQL. When I was working with SQL statements that returned many records, I had no patience to wait for all the records to be completely returned and I normally stopped the SQL execution once the first few records were returned. It saved me a lot of time so that I could test multiple rewrites in a short time. This testing approach was good, since at that time Oracle provided only the Nested Loop join. The Nested Loop was the lowest cost join method for the machines in that age. I still remember my first project was using an Oracle database (I forgot the version number) running on a Digital machine with 48M RAM. A Sort Merge join would need too much memory for this kind of machine.

Today, we normally have multiple gigabytes of memory in our Oracle servers. Oracle now provides more join methods such as Sort Merge and Hash Join to fully utilize our machine’s memory and CPU. We should not base our decision whether a SQL is a better alternative solely on the time it takes the SQL statement to execute. We should take into account how the SQL statement is used in the application. Let me use a simple SQL to explain:

select * from employee,
              department
 where emp_dept=dpt_id

Basically for this kind of simple SQL statements, the Oracle internal SQL optimizer can perform any join method from the basic Nested Loop, Sort Merge, or Hash Join. You can use the Oracle optimization hints to influence Oracle to use any execution plan you want. For a Nested Loop join, you use the USE_NL hint or FIRST_ROWS. You may be wonder why the FIRST_ROWS hint will result in a Nested Loop join. Hash Join has to build a hash table and Sort Merge has to sort a table before they can return any records at all, so when you tell Oracle to process a SQL statement to give you the first record as fast possible, Oracle will prefer a Nested Loop in spite of its relatively higher cost. For an online query that needs to display only the first one or two pages of records from a cursor, the Nested Loop join is definitely a good choice since it provides the first records faster than the other two join methods. For example; if you have a query in a Datawindow in PowerBuider or TQuery in Delphi and the end users will not scroll down to see more than one or two pages, you can use the FIRST_ROWS hint in your SQL statement to speed up the response time for the user and save the user from having to wait for almost the entire SQL to be processed with Sort Merge or Hash Join. For example, if a SQL returns 1000 records, a Nested Loop join can quickly give you 20 records in a SQL cursor and display them on the screen. The user may only want to review the first 20 records and then close the cursor immediately, This process only spent around 20/1000=2% of the total workload it would take to retrieve the entire 1000 records for this SQL. If a Sort Merge is used when you want the first 20 records to be displayed on screen, Oracle has to finish the Sort operation first and then return the records in the Merge stage, so, most of the heavy sort operation is already done before it can return any records. Therefore you will not save much workload by breaking the cursor fetching after 20 records when using a Sort Merge join.

Here is the SQL statement with the FIRST_ROWS hint and the resulting execution plan:

select /*+First_Rows */ * from employee,
                               department
 where emp_dept=dpt_id

If you are not quite sure how the SQL statement you are tuning is going to be use in your application, it is best to use the default Oracle behavior which is good in most cases. Of course, you can use our Quest SQL Optimizer to find a better rewrite with has both a good response time (retrieving the first few records) and a good elapsed time (retrieving all records).

Let’s get back to today’s topic. You can see that a SQL rewrite which has a fast response time is normally generated by a Nested Loop join operation. The Nested Loop join is good only in certain circumstances such as for a small result set and when the driving path is correct (that is when the smaller table or result-set is looping a large table or result-set using a unique index search). Other than that, the Sort Merge or Hash Join will be a safe choice. It is common in modern relational databases that the cost of the Nested Loop is relatively higher than the Sort Merge or Hash Join, since the driving path will not affect the performance too much in Sort Merge or Hash Join. But a wrong driving path in Nested Loop join may be a disaster in your application, therefore, database vendors prefer not to take this risk in designing their SQL optimizer and give the Nested Loop join a higher cost.

The SQL statement that I have used to illustrate this point is a simple SQL. For complex SQL, there is no single rule which is always true for you to follow in order to pick out the best join method to use. It is better that you try the different methods and see which one produces the best results in your specific database environment and application. Quest SQL Optimizer makes this search for performance a simple process by rewriting the SQL syntax for you and testing the SQL alternatives.

Permalink |  Trackback
Search Blog Entries
 
Copyright 2010 by Quest Software  | Terms Of Use | Privacy Statement | Contact Us