Showing posts with label Joins. Show all posts
Showing posts with label Joins. Show all posts

Saturday, December 5, 2009

Practice Oracle Joins Examples

Before starting this lab let's assume that you have the following two files Lab1_initialization.sql and  2.PUPBLD.SQL

Lab1_initialization.sql



DROP USER DBM449_USER CASCADE;

CREATE USER DBM449_USER
IDENTIFIED BY DEVRY
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;

GRANT CONNECT, RESOURCE TO DBM449_USER;

GRANT CREATE MATERIALIZED VIEW, CREATE DATABASE LINNK TO DBM449_USER;

CONN DBM449_USER/DEVRY@db####.WORLD

DROP TABLE CLIENT;
DROP TABLE COURSE;
DROP TABLE COURSE_ACTIVITY;
DROP TABLE CORP_EXTRACT1;
DROP TABLE CORP_EXTRACT2;

CREATE TABLE CLIENT (
CLIENT_NO CHAR(8) PRIMARY KEY,
CLIENT_COMPANY VARCHAR(35) NOT NULL,
CLIENT_NAME VARCHAR(35) NOT NULL,
CLIENT_EMAIL VARCHAR(35),
CLIENT_PROGRAM CHAR(3) NOT NULL,
CLIENT_SCORE NUMBER NOT NULL);


CREATE TABLE COURSE (
COURSE_CODE CHAR(8)PRIMARY KEY,
COURSE_NAME VARCHAR(35) NOT NULL,
COURSE_DATE DATE NOT NULL,
COURSE_INSTRUCTOR VARCHAR(35) NOT NULL,
COURSE_LOCATION VARCHAR(20) NOT NULL);


CREATE TABLE COURSE_ACTIVITY (
ACTIVITY_CODE CHAR(8) PRIMARY KEY,
CLIENT_NO CHAR(8) NOT NULL,
COURSE_CODE CHAR(8) NOT NULL,
GRADE CHAR(1),
INSTR_NOTES VARCHAR (50));


CREATE TABLE CORP_EXTRACT1 (
EXTRACT_NO CHAR(3) PRIMARY KEY,
CLIENT_NO CHAR(8) NOT NULL,
CLIENT_NAME VARCHAR(35) NOT NULL,
CLIENT_EMAIL VARCHAR(35),
CLIENT_COMPANY VARCHAR(35) NOT NULL,
CLIENT_PROGRAM CHAR(3) NOT NULL,
CLIENT_SCORE NUMBER NOT NULL,
COURSE_NAME VARCHAR(35) NOT NULL,
COURSE_DATE DATE NOT NULL,
COURSE_INSTRUCTOR VARCHAR(35) NOT NULL,
COURSE_LOCATION VARCHAR(20) NOT NULL,
Course_STATUS VARCHAR(10) NOT NULL);

CREATE TABLE CORP_EXTRACT2 (
EXTRACT_NO NUMBER PRIMARY KEY,
CLIENT_NO CHAR(8) NOT NULL,
CLIENT_NAME VARCHAR(45) NOT NULL,
CLIENT_EMAIL VARCHAR(35),
CLIENT_COMPANY VARCHAR(35) NOT NULL,
CLIENT_PROGRAM CHAR(8) NOT NULL,
CLIENT_SCORE NUMBER NOT NULL,
COURSE_NAME VARCHAR(35) NOT NULL,
COURSE_DATE DATE NOT NULL,
COURSE_INSTRUCTOR VARCHAR(35) NOT NULL,
COURSE_LOCATION VARCHAR(20) NOT NULL,
Course_STATUS VARCHAR(10) NOT NULL);




/* Loading data rows */
/* Turn Escape character on */
/* Default escape character "\" */
/* Used to enter special characters (&) */
SET ESCAPE ON;


/* CLIENT rows */
INSERT INTO CLIENT VALUES('C2122542','Bryson, Inc.' ,'Smithson','smithson@bryson.com' ,'DBA',47);
INSERT INTO CLIENT VALUES('C2122356','SuperLoo, Inc.' ,'Flushing','flushing@superloo.com' ,'DBA',38);
INSERT INTO CLIENT VALUES('C2123871','D\&E Supply' ,'Singh' ,'rsingh@desupply.com' ,'EAI',42);
INSERT INTO CLIENT VALUES('C2134452','Gomez Bros.' ,'Ortega' ,'ortega@gomez.com' ,'DBA',39);
INSERT INTO CLIENT VALUES('C2256716','Dome Supply' ,'Smith' ,'smith@dome' ,'ADM',41);

/* COURSE rows */
INSERT INTO COURSE VALUES('DBA12345','DBA 101' ,'03-OCT-2005','Phung' ,'Kaanapali');
INSERT INTO COURSE VALUES('DBA12346','Advanced DBA' ,'23-NOV-2005','Browne' ,'San Mateo');
INSERT INTO COURSE VALUES('EAI12345','EAI Intro' ,'30-NOV-2005','Luss' ,'Danbury');
INSERT INTO COURSE VALUES('DBA12347','DBA 101' ,'08-JAN-2006','Fiorillo' ,'Paramus');
INSERT INTO COURSE VALUES('DBA12348','DBA 101' ,'28-FEB-2006','Majmundar' ,'Racine');

/* COURSE ACTIVITY rows */
INSERT INTO COURSE_ACTIVITY VALUES('A0000001','C2122542','DBA12345','A',NULL);
INSERT INTO COURSE_ACTIVITY VALUES('A0000002','C2122356','DBA12347','F',NULL);
INSERT INTO COURSE_ACTIVITY VALUES('A0000003','C2134452','DBA12345','B',NULL);
INSERT INTO COURSE_ACTIVITY VALUES('A0000004','C2122542','DBA12346','A',NULL);
INSERT INTO COURSE_ACTIVITY VALUES('A0000005','C2123871','EAI12345','A',NULL);
INSERT INTO COURSE_ACTIVITY VALUES('A0000006','C2122356','DBA12345',NULL,NULL);

/* CORP_EXTRACT1 rows */
INSERT INTO CORP_EXTRACT1 VALUES ('001','C2122542','Smithson','smithson@bryson.com','Bryson, Inc.','DBA',47,'EAI Intro','01-MAR-2007','Luss','Hilo','Enrolled');
INSERT INTO CORP_EXTRACT1 VALUES ('002','C2122356','Flushing','flushing@superloo.com','SuperLoo, Inc.','DBA',38,'DBA 101','03-OCT-2005','Luss','Hilo','Dropped');
INSERT INTO CORP_EXTRACT1 VALUES ('003','C2172249','Bizet','gbizet@bryson.com','Bryson, Inc.','EAI',44,'EAI Intro','01-MAR-2007','Luss','Hilo','Enrolled');

COMMIT;

GRANT SELECT ON COURSE TO PUBLIC;
GRANT SELECT ON CLIENT TO PUBLIC;
GRANT SELECT ON COURSE_ACTIVITY TO PUBLIC;

SET ESCAPE OFF;



2.PUPBLD.SQL





conn system/manager@db1000.world

drop synonym product_user_profile;

create table sqlplus_product_profile as
select product, userid, attribute, scope, numeric_value, char_value,
date_value from product_user_profile;

drop table product_user_profile;
alter table sqlplus_product_profile add (long_value long);

rem +---------------------------------------+
rem | Create SQLPLUS_PRODUCT_PROFILE from scratch |
rem +---------------------------------------+

create table sqlplus_product_profile
(
product varchar2 (30) not null,
userid varchar2 (30),
attribute varchar2 (240),
scope varchar2 (240),
numeric_value decimal (15,2),
char_value varchar2 (240),
date_value date,
long_value long
);

rem
rem Remove SQL*Plus V3 name for sqlplus_product_profile
rem
drop table product_profile;


rem +------------------------------------------------------------------+
rem | Create the view PRODUCT_PRIVS and grant access to that |
rem +------------------------------------------------------------------+

drop view product_privs;
create view product_privs as
select product, userid, attribute, scope,
numeric_value, char_value, date_value, long_value
from sqlplus_product_profile
where userid = 'PUBLIC' or user like userid;

grant select on product_privs to public;
drop public synonym product_profile;
create public synonym product_profile for system.product_privs;
drop synonym product_user_profile;
create synonym product_user_profile for system.sqlplus_product_profile;
drop public synonym product_user_profile;
create public synonym product_user_profile for system.product_privs;

rem +---------------------------------------------------------------+
rem | CONNECT BACK AS THE SYS USER |
rem +---------------------------------------------------------------+

conn sys/oracle@DB###.world as sysdba
Exercise Description
My colleague, Ann Henry, operates a regional training center for a commercial software organization. She created a database to track client progress so she can analyze effectiveness of the certification program. CLIENT, COURSE, and COURSE_ACTIVITY are three of the tables in her database. The CLIENT table contains client name, company, client number, pre-test score, certification program and email address. The COURSE_ACTIVITY table contains client number, course code, grade, and instructor notes. The COURSE table contains the course code, course name, instructor, course date, and location. Although she and her instructors enter much of the data themselves, some of the data are extracted from the corporate database and loaded into her tables.Loading the initial data was easy. For grade entry at the end of each course, a former employee created a data entry form for the instructors. Updating most client information and generating statistics on client progress is not easy because Ann does not know much SQL. For now, she exports the three tables into three spreadsheets. To look up a grade in the COURSE_ACTIVITY spreadsheet, she first has to look up client number in the CLIENT spreadsheet. While this is doable, it is certainly not practical. For statistics, she sorts the data in the COURSE_ACTIVITY spreadsheet using multiple methods to get the numbers she needs.Every month, Ann's database tables need to be refreshed to reflect changes in the corporate database. Ann describes this unpleasant task. She manually compares the contents of newly extracted data from corporate to the data in her spreadsheets, copies in the new values, and then replaces the database contents with the new values.Ann needs our help. Let’s analyze her situation and determine what advanced SQL she could use to make her tasks easier.

L A B O V E R V I E W

Scenario/Summary
The purpose of this lab is to explore join operators to determine which, if any, are appropriate for solving Ann's business problems, as described in this week's lecture.Since Ann prefers to work from Excel spreadsheets, she wants her CLIENT and COURSE_ACTIVITY tables exported into one spreadsheet rather than two, as she is currently using. We need to determine which, if any, of the join operators will provide the data she wants for the single spreadsheet. (Note: we will not perform the export, just determine how to retrieve the necessary data.) Using the spreadsheet, she will be able to determine:
  1. Which course(s) a specific client has taken
  2. What grade(s) a specific client has earned in a specific course
  3. Which clients did not take any courses
  4. Which courses were not taken by any client
Here are results from DESCRIBE commands that show structure (columns and their data types) of tables CLIENT and COURSE_ACTIVITY. You may refer to it while constructing your queries. For this lab you will be creating several documents. First, write your queries in Notepad to create a script file that will contain all of the queries asked for in lab steps 4 through 13. You can (and should) test each query as you write it to make sure that it works and is returning the correct data. Once you have all of your queries written then create a SPOOL session and run your entire script file. Be sure that you execute a SET ECHO ON session command before running the file so that both the query and the output will be captured in the SPOOL file. IMPORTANT: If you are using Windows Vista you will need to create a directory on your C: drive to SPOOL your file into. Vista will not allow you to write a file directly to the C: drive. This will give you two files for the lab. The third file will the be the Lab1 Report document found in Doc Sharing. You will need to put your responses to the questions asked in the various lab steps.Now let's begin. 

L A B S T E P S

STEP 1: Start Oracle SQL*Plus via Citrix
Your browser may not support display of this image.
Start Citrix Metaframe. Select SQL Plus and log in to your database instance. Use "sys" as User Name, and "oracle" as the Password. Enter the Host String as "DB9999.world as sysdba" where 9999 is the database number you have been assigned.
STEP 2: Initialize tables
Your browser may not support display of this image.
Download the Lab1_initialization.sql and pupbld.sql files associated with the links to your C: drive or to the F: drive in your Citrix environment. You will need to open each of the files and edit the connection string to match your instance name. Once you have done this then run the pupbld.sql script first (DO NOT copy and paste it) in your SQL*Plus session. The script will create the product_user_profile synonym in the SYSTEM account which will be used each time you log in as a normal user. Next run the lab1_initalization.sql script in your session. The script will create a new user (DBM449_USER) that will be used in various labs in this course. Disregard the DROP TABLE error messages. They occur because the script is designed to work regardless of whether you have already created the tables or not. This way, you may run it if you ever decide to resent the contents of your tables to the original values. When you run the script for the first time, the error messages appear as you attempt to drop tables that do not exist.Once the script has finished you will be logged into the new user and ready to start your lab.
STEP 3: Verify your tables
Your browser may not support display of this image.
You want to verify that everything completed successfully. To do this execute a SELECT * FROM TAB statement to make sure all 5 tables were created and then you can execute a SELECT COUNT(*) FROM statement using each of the table names. You should find the following numbers of records for each table.
  • CLIENT table - 5 rows
  • COURSE table - 5 rows
  • COURSE_ACTIVITY table - 6 rows
  • CORP_EXTRACT1 table - 3 rows
  • CORP_EXTRACT2 table - 0 rows
STEP 4: Using the FULL OUTER JOIN operator
Your browser may not support display of this image.
Join the CLIENT and COURSE_ACTIVITY tables using a FULL OUTER JOIN.
  • Write and execute the SQL statement that produces the client number and name, course code and grade that the client got in this course.
Will the FULL OUTER JOIN be helpful to Ann? Place your response in the lab report document for this step.
STEP 5: Using the RIGHT OUTER JOIN operator
Your browser may not support display of this image.
Join the CLIENT and COURSE_ACTIVITY tables using a RIGHT OUTER JOIN.
  • Write and execute the SQL statement that produces the client number and name, course code and grade that the client got in this course.
Will the RIGHT OUTER JOIN be helpful to Ann? Place your response in the lab report document for this step.
STEP 6: Using the LEFT OUTER JOIN operator
Your browser may not support display of this image.
Join the CLIENT and COURSE_ACTIVITY tables using a LEFT OUTER JOIN.
  • Write and execute the SQL statement that produces the client number and name, course code and grade that the client got in this course.
Will the LEFT OUTER JOIN be helpful to Ann? Place your response in the lab report document for this step.
STEP 7: Using the NATURAL JOIN operator
Your browser may not support display of this image.
Join the CLIENT and COURSE_ACTIVITY tables using a NATURAL JOIN.
  • Write and execute the SQL statement that produces the client number and name, course code and grade that the client got in this course.
  • Will the NATURAL JOIN be helpful to Ann? Place your response in the lab report document for this step.
STEP 8: Using the INNER JOIN operator
Your browser may not support display of this image.
Join the CLIENT and COURSE_ACTIVITY tables using a INNER JOIN.
  • Write and execute the SQL statement that produces the client number and name, course code and grade that the client got in this course.
Will the INNER JOIN be helpful to Ann? Place your response in the lab report document for this step.Write a conclusion based on the five steps above, which join - if any - should Ann use to populate the spreadsheet that can answer her questions. 
STEP 9: Using the UNION operator
Your browser may not support display of this image.
Examine the clients and courses in Ann’s tables and the CORP_EXTRACT1 table using the UNION operator.
  • Write and execute the SQL statement that examines client numbers in CLIENT and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines client numbers in COURSE_ACTIVITY and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines course names in COURSE and CORP_EXTRACT1.
Which of these statements, if any, will be helpful to Ann? Place your response in the lab report document for this step.
STEP 10: Using the UNION ALL operator
Your browser may not support display of this image.
Examine the clients and courses in Ann’s tables and the CORP_EXTRACT1 table using the UNION ALL operator.
  • Write and execute the SQL statement that examines client numbers in CLIENT and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines client numbers in COURSE_ACTIVITY and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines course names in COURSE and CORP_EXTRACT1.
Which of these statements, if any, will be helpful to Ann? Place your response in the lab report document for this step.
STEP 11: Using the INTERSECT operator
Your browser may not support display of this image.
Examine the clients and courses in Ann’s tables and the CORP_EXTRACT1 table using the INTERSECT operator.
  • Write and execute the SQL statement that examines client numbers in CLIENT and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines client numbers in COURSE_ACTIVITY and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines course names in COURSE and CORP_EXTRACT1.
Which of these statements, if any, will be helpful to Ann? Place your response in the lab report document for this step.
STEP 12: Using the MINUS operator
Your browser may not support display of this image.
Examine the clients and courses in Ann’s tables and the CORP_EXTRACT1 table using the MINUS operator.
  • Write and execute the SQL statement that examines client numbers in CLIENT and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines client numbers in COURSE_ACTIVITY and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines course names in COURSE and CORP_EXTRACT1.
Which of these statements, if any, will be helpful to Ann? Place your response in the lab report document for this step.
STEP 13: Using subqueries
Your browser may not support display of this image.
Examine the clients and courses in Ann’s tables and the CORP_EXTRACT1 table using a subquery with NOT IN operator.
  • Write and execute the SQL statement that examines client numbers in CLIENT and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines client numbers in COURSE_ACTIVITY and CORP_EXTRACT1.
  • Write and execute the SQL statement that examines course names in COURSE and CORP_EXTRACT1.
Which of these statements, if any, will be helpful to Ann? Place your response in the lab report document for this step.
Related Documents

Basic Oracle Sql Exercise

Wednesday, June 18, 2008

Optimizer choise of Outer Join in execution plan

Nested Loop Outer Joins
--------------------------------------------

This operation is used when an outer join is used between two tables. The outer join returns the outer table rows, even when there are no corresponding rows in the inner table.

In a regular outer join, the optimizer chooses the order of tables based on the cost. However, in a nested loop outer join, there is not alternative. The order of tables is determined by the join condition. The outer table, with rows that are being preserved, is used to drive to the inner table.

To use nested loop outer join explicitly USE_NL hint can be used.

Here is an example to use nested loop outer joins in oracle.

Based on the data in Example of Outer Join

SQL> select CustName, OrderDate, Address
from Customers c Right outer join Orders o
on c.CustNo = o.CustNo ;



Execution Plan
----------------------------------------------------------
Plan hash value: 1206303405

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 380 | 4 (0)| 00:00:01 |
| 1 | NESTED LOOPS OUTER | | 5 | 380 | 4 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL | ORDERS | 5 | 55 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| CUSTOMERS | 1 | 65 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | SYS_C006142 | 1 | | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Hash Join Outer Joins
--------------------------------------------

The optimizer uses hash joins for processing an outer join if the data volume is high enough to make the hash join method efficient or if it is not possible to drive from the outer table to inner table.

Based on the data in Examples of All outer joins in Oracle

SQL> select a.n, b.k from table_a a left outer join table_b b on a.k=b.k;


10000 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2129125445

------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 166K| 603 (3)| 00:00:08 |
|* 1 | HASH JOIN OUTER | | 10000 | 166K| 603 (3)| 00:00:08 |
| 2 | TABLE ACCESS FULL| TABLE_A | 10000 | 90000 | 8 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| TABLE_B | 1007K| 7873K| 589 (2)| 00:00:08 |
------------------------------------------------------------------------------

Sort Merge Outer Joins
--------------------------------------------

When an outer join cannot drive from the outer table to the inner table, it cannot use a hash join or nested loop joins. Then it uses the sort merge outer join for performing the join operation.

SQL> select CustName, OrderDate, Address
from Customers c left outer join Orders o
on c.CustNo = o.CustNo ;


Based on the data in Example of Outer Join


Execution Plan
----------------------------------------------------------
Plan hash value: 1595815448

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 380 | 6 (17)| 00:00:01 |
| 1 | MERGE JOIN OUTER | | 5 | 380 | 6 (17)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| CUSTOMERS | 4 | 260 | 2 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | SYS_C006142 | 4 | | 1 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 5 | 55 | 4 (25)| 00:00:01 |
| 5 | TABLE ACCESS FULL | ORDERS | 5 | 55 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Full Outer Joins
---------------------------------------------

A full outer join acts like a combination of the left and right outer joins. you can specify FULL OUTER JOIN.

Curtesian Join in Execution Plan

Cartesian Join:
--------------------------

•A Cartesian join is used when one or more of the tables does not have any join conditions to any other tables in the statement. The optimizer joins every row from one data source with every row from the other data source, creating the Cartesian product of the two sets.

•The optimizer uses Cartesian joins when it is asked to join two tables with no join conditions. In some cases, a common filter condition between the two tables could be picked up by the optimizer as a possible join condition.

•In other cases, the optimizer may decide to generate a Cartesian product of two very small tables that are both joined to the same large table.

•Applying the ORDERED hint, instructs the optimizer to use a Cartesian join. By specifying a table before its join table is specified, the optimizer does a Cartesian join.

With the example of creation script of table_a in example Example of Using Hints in Index,
SQL> create table table_e as select level a from dual connect by level<=100;
Table created.

SQL> select a.n, b.a from table_a a , table_e b;


1000000 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1945448542

--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000K| 15M| 627 (2)| 00:00:08 |
| 1 | MERGE JOIN CARTESIAN| | 1000K| 15M| 627 (2)| 00:00:08 |
| 2 | TABLE ACCESS FULL | TABLE_E | 100 | 1300 | 3 (0)| 00:00:01 |
| 3 | BUFFER SORT | | 10000 | 30000 | 624 (2)| 00:00:08 |
| 4 | TABLE ACCESS FULL | TABLE_A | 10000 | 30000 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement

Sort Merge Joins

Overview of Sort Merge Joins
------------------------------------------------

Sort merge joins can be used to join rows from two independent sources. Hash joins generally perform better than sort merge joins. On the other hand, sort merge joins can perform better than hash joins if both of the following conditions exist:

•The row sources are sorted already.
•A sort operation does not have to be done.

Sort merge joins are useful when the join condition between two tables is an inequality condition (but not a nonequality) like <, <=, >, or >=. Sort merge joins perform better than nested loop joins for large data sets. You cannot use hash joins unless there is an equality condition.
In a merge join, there is no concept of a driving table. The join consists of two steps:

1.Sort join operation: Both the inputs are sorted on the join key.
2.Merge join operation: The sorted lists are merged together.

If the input is already sorted by the join column, then a sort join operation is not performed for that row source.

When the Optimizer Uses Sort Merge Joins
-----------------------------------------------------

The optimizer can choose a sort merge join over a hash join for joining large amounts of data if any of the following conditions are true:

•The join condition between two tables is not an equi-join.
•Because of sorts already required by other operations, the optimizer finds it is cheaper to use a sort merge than a hash join.

Sort Merge Join Hints
--------------------------------------------

To instruct the optimizer to use a sort merge join, apply the USE_MERGE hint. You might also need to give hints to force an access path.

There are situations where it is better to override the optimize with the USE_MERGE hint.

Example of Sort Merge Joins
----------------------------------


Based on the data in Example of using Index by Hints
SQL> select a.n, b.b from table_a a , table_b b where a.k>b.k;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 3680082791

---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 21 | | 5265 (2)| 00:01:04 |
| 1 | MERGE JOIN | | 1 | 21 | | 5265 (2)| 00:01:04 |
| 2 | SORT JOIN | | 10000 | 90000 | 408K| 50 (2)| 00:00:01 |
| 3 | TABLE ACCESS FULL| TABLE_A | 10000 | 90000 | | 8 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 1007K| 11M| 38M| 5214 (2)| 00:01:03 |
| 5 | TABLE ACCESS FULL| TABLE_B | 1007K| 11M| | 590 (2)| 00:00:08 |
---------------------------------------------------------------------------------------

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

4 - access(INTERNAL_FUNCTION("A"."K")>INTERNAL_FUNCTION("B"."K"))
filter(INTERNAL_FUNCTION("A"."K")>INTERNAL_FUNCTION("B"."K"))

Hash Joins

Overview of Hash Joins
------------------------------------------

•Hash joins are used for joining large data sets.

•The optimizer uses the smaller of two tables or data sources to build a hash table on the join key in memory.

•It then scans the larger table, probing the hash table to find the joined rows.

•This method is best used when the smaller table fits in available memory.

•The cost is then limited to a single read pass over the data for the two tables.

When the Optimizer Uses Hash Joins
----------------------------------------------------

The optimizer uses a hash join to join two tables if they are joined using an equijoin and if either of the following conditions are true:

•A large amount of data needs to be joined.
•A large fraction of a small table needs to be joined.

Hash Join Hints
--------------------------------------------

Apply the USE_HASH hint to instruct the optimizer to use a hash join when joining two tables together.

Hash Join Example:
--------------------------------

You can see the hash join example in my post Use of Hint to use Index

Tuesday, June 17, 2008

Nested Loop Joins

Overview Nested Loop Joins
---------------------------------------

•Oracle always join two of the tables. In join one row set is called inner, and the other is called outer. If the inner table row set is dependent or derived from outer table then nested loop join performs better.

•But if the inner table's access path is independent of the outer table, then the same rows are retrieved for every iteration of the outer loop, degrading performance considerably. In such cases, hash joins joining the two independent row sources perform better.

•Nested loop joins are useful when small subsets of data are being joined and if the join condition is an efficient way of accessing the second table.

How Nested Loop Join Works
---------------------------------------------------

In case of nested loop join the following steps is involved.
1)The optimizer first determine the driving table and designates it as the outer table.

2)The optimizer designate other table (driven/dependent) as inner table.

3)For every row in the outer table, Oracle accesses all the rows in the inner table. The outer loop is for every row in outer table and the inner loop is for every row in the inner table. The outer loop appears before the inner loop in the execution plan, as follows:

NESTED LOOPS
outer_loop
inner_loop


When the Optimizer Uses Nested Loop Joins
-----------------------------------------------------------

•The optimizer uses nested loop joins when joining small number of rows, with a good driving condition between the two tables. You drive from the outer loop to the inner loop, so the order of tables in the execution plan is important.

•The outer loop is the driving row source. It produces a set of rows for driving the join condition. The row source can be a table accessed using an index scan or a full table scan. Also, the rows can be produced from any other operation. For example, the output from a nested loop join can be used as a row source for another nested loop join.

•The inner loop is iterated for every row returned from the outer loop, ideally by an index scan. If the access path for the inner loop is not dependent on the outer loop, then you can end up with a Cartesian product; for every iteration of the outer loop, the inner loop produces the same set of rows. Therefore, you should use other join methods when two independent row sources are joined together.

Nested Loop Join Hints
------------------------------------------

If the optimizer is choosing to use some other join method, you can use the USE_NL(table1 table2) hint, where table1 and table2 are the aliases of the tables being joined.

Nested Loop Join Example
------------------------------------------

Here I used the script and data that is listed in post Examples of Outer Joins
SQL> select address, orderdate from customers c, orders o where c.custno=o.custno;


Execution Plan
----------------------------------------------------------
Plan hash value: 3442778016

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 275 | 4 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 5 | 275 | 4 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL | ORDERS | 5 | 55 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| CUSTOMERS | 1 | 44 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | SYS_C006142 | 1 | | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

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

4 - access("C"."CUSTNO"="O"."CUSTNO")

Here the outer loop is | 2 | TABLE ACCESS FULL | ORDERS |
And inner loop is | 3 | TABLE ACCESS BY INDEX ROWID| CUSTOMERS |
|* 4 | INDEX UNIQUE SCAN |

How the Query Optimizer Chooses Execution Plans for Joins

In order to know various types of joins search inside my blog.
In a join, one row set is called inner, and the other is called outer.
To choose an execution plan for a join statement, the optimizer must make these interrelated decisions.

1)Access Paths
2)Join Method: To join each pair of row sources, Oracle must perform a join operation. Join methods include nested loop, sort merge, cartesian, and hash joins.
3)Join Order: To execute a statement that joins more than two tables, Oracle joins two of the tables and then joins the resulting row source to the next table. This process is continued until all tables are joined into the result.

During choosing an execution plan the query optimizer considers the following:

The optimizer first determines whether joining two or more tables definitely results in a row source containing at most one row. If such a situation exists, then the optimizer places these tables first in the join order. The optimizer then optimizes the join of the remaining set of tables.

With the query optimizer, the optimizer generates a set of execution plans, according to possible join orders, join methods, and available access paths. The optimizer then estimates the cost of each plan and chooses the one with the lowest cost. The optimizer estimates costs in the following ways:


•The cost of a nested loops operation is based on the cost of reading each selected row of the outer table and each of its matching rows of the inner table into memory. The optimizer estimates these costs using the statistics in the data dictionary.

•The cost of a sort merge join is based largely on the cost of reading all the sources into memory and sorting them.

•The cost of a hash join is based largely on the cost of building a hash table on one of the input sides to the join and using the rows from the other of the join to probe it.

•A smaller sort area size(That is settings of PGA_AGGREGATE_TARGET) is likely to increase the cost for a sort merge join because sorting takes more CPU time and I/O in a smaller sort area.

•A larger multiblock read count is likely to decrease the cost for a sort merge join in relation to a nested loop join.

Index Skip, Full, Fast Full Index, Index Joins Bitmap Indexes Scan

A)Index Skip Scan
----------------------------------------

As the name suggest index skip scan does not scan complete index. But it scan of the subindexes.

Index skip scan lets a composite index be split logically into smaller subindexes. In skip scanning, the initial column of the composite index is not specified in the query. In other words, it is skipped.

The number of logical subindexes is determined by the number of distinct values in the initial column. Skip scanning is advantageous if there are few distinct values in the leading column of the composite index and many distinct values in the nonleading key of the index.

Suppose if I make a make a composite index with two columns sex and id. The leading column sex contains only two distinct columns. Now if I query with non-leading column that is with id column then index skip scan will be used.

Example:
------------------

SQL> create table test_skip_scan (sex varchar2(1), id number, address varchar2(20));
Table created.

SQL> create index test_skip_scan_I on test_skip_scan(sex,id);

Index created.

SQL> begin
for i in 1 .. 10000
loop
insert into test_skip_scan values(decode(remainder(abs(round(dbms_random.value(2,20),0)),2),0,'M','F'),i,null);
end loop;
end;
/

PL/SQL procedure successfully completed.

SQL> analyze table test_skip_scan estimate statistics;
Table analyzed.

SQL> select * from test_skip_scan where id=1;


Execution Plan
----------------------------------------------------------
Plan hash value: 2410156502

------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 9 | 4 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_SKIP_SCAN | 1 | 9 | 4 (0)| 00:00:01 |
|* 2 | INDEX SKIP SCAN | TEST_SKIP_SCAN_I | 1 | | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------

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

2 - access("ID"=1)
filter("ID"=1)

B)Index Fast Full Scan
---------------------------------------

Fast full index scans are an alternative to a full table scan when the index contains all the columns that are needed for the query, and at least one column in the index key has the NOT NULL constraint.

A fast full scan accesses the data in the index itself, without accessing the table.

It cannot be used to eliminate a sort operation, because the data is not ordered by the index key.

It reads the entire index using multiblock reads, unlike a full index scan, and can be parallelized.

Fast full index scans cannot be performed against bitmap indexes.

You can specify fast full index scans with the initialization parameter OPTIMIZER_FEATURES_ENABLE or the INDEX_FFS hint.

Example:
-----------------
SQL> select /*+INDEX_FFS(test_skip_scan)*/ sex,id from test_skip_scan;


10000 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4280781105

-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 40000 | 7 (0)| 00:00:01 |
| 1 | INDEX FAST FULL SCAN| TEST_SKIP_SCAN_I | 10000 | 40000 | 7 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------


C)Index Joins
-------------------------

An index join is a hash join of several indexes that together contain all the table columns that are referenced in the query. If an index join is used, then no table access is needed, because all the relevant column values can be retrieved from the indexes. An index join cannot be used to eliminate a sort operation.

You can specify an index join with the INDEX_JOIN hint. For more information on the INDEX_JOIN hint.

SQL> select sex,id from test_skip_scan where id in (select col1 from test_tab);


1000 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1059662925

----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 999 | 6993 | 9 (12)| 00:00:01 |
|* 1 | HASH JOIN RIGHT SEMI | | 999 | 6993 | 9 (12)| 00:00:01 |
| 2 | INDEX FAST FULL SCAN| TEST_TAB_I | 1000 | 3000 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | TEST_SKIP_SCAN | 10000 | 40000 | 6 (0)| 00:00:01 |
----------------------------------------------------------------------------------------

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

1 - access("ID"="COL1")


D)Bitmap Indexes
-----------------------------------

A bitmap join uses a bitmap for key values and a mapping function that converts each bit position to a rowid. Bitmaps can efficiently merge indexes that correspond to several conditions in a WHERE clause, using Boolean operations to resolve AND and OR conditions.

Bitmap indexes and bitmap join indexes are available only if you have purchased the Oracle Enterprise Edition.

Tuesday, June 3, 2008

Example of Antijoin, Semijoin, Curtesian Product,Self join

Antijoin Example:
------------------------

If I want to wish to select a list of students who are not in a particular set departments that I can use antijoin as below.

SQL>SELECT * FROM student
WHERE deptid NOT IN
(SELECT deptid FROM dept
WHERE deptid = 3)
ORDER BY NAME;

STDID NAME DEPTID
---------- --------------- ----------
24101 Raju 1

Semijoin Example:
----------------------

Whenever only one row needs to be returned from the departments table, even though many rows in the employees table might match the subquery.
SQL>SELECT * FROM dept
WHERE EXISTS
(SELECT * FROM student
WHERE dept.deptid = student.deptid
)
ORDER BY deptname;

DEPTID DEPTNAME
---------- ----------
3 CSE

Crossjoin Example: Cartesian Product
---------------------------------

SQL> insert into student values(22440,'Adu',2);
1 row created.

SQL> select name,deptname from dept CROSS JOIN student;
NAME DEPTNAME
--------------- ----------
Rafi EEE
Raju EEE
Arju EEE
Adu EEE
Rafi CSE
Raju CSE
Arju CSE
Adu CSE

8 rows selected.

Self Join Example:
---------------------

A self join to return the name of each employee along with the name of the employee's manager.
SELECT e1.last_name||' works for '||e2.last_name
"Employees and Their Managers"
FROM employees e1, employees e2
WHERE e1.manager_id = e2.employee_id


Related Documents:
------------------------

Joins in Oracle
Example of Outer and Equijoin
Difference between inner join and outer join in oracle
Difference between join,inner join, natural join and equijoin in oracle

Monday, June 2, 2008

Difference between join, Inner join,Equijoin and Natural Join

An inner join is a join with a join condition that may contain both equality or non-equality sign whereas an equijoin is a join with a join condition that only contain only equality sign.
So we can say an equijoin is a type of inner join containing (Equal)= operator in the join condition.

It is good to know the difference between join and INNER JOIN keywoed. Actually there is no difference. If we write JOIN then by default INNER JOIN is performed. In the example it is also shown.
The following example will make you more clear.

In this example I used data as in example of Difference between Inner join and Outer join
SQL> select s.name,d.deptname from dept d, student s where d.deptid=s.deptid;
NAME DEPTNAME
--------------- ----------
Rafi CSE
Arju CSE

This example represents both INNER join and equijoin.
SQL> select s.name,d.deptname from dept d INNER JOIN student s on d.deptid=s.deptid;
NAME DEPTNAME
--------------- ----------
Rafi CSE
Arju CSE

Above example also represents both INNER join and equijoin.
SQL> select s.name,d.deptname from dept d INNER JOIN student s on d.deptid<>s.deptid;

NAME DEPTNAME
--------------- ----------
Rafi EEE
Raju EEE
Arju EEE
Raju CSE

Above example represents an inner join but not a equijoin.
SQL> select s.name,d.deptname from dept d JOIN student s on d.deptid<>s.deptid;

NAME DEPTNAME
--------------- ----------
Rafi EEE
Raju EEE
Arju EEE
Raju CSE

Above example show JOIN and INNER join keyword is same. If we don't specify INNER then by default inner join is performed.

Now let's have a look at natural join.
SQL> desc dept;
Name Null? Type
----------------------------------------- -------- ----------------------------
DEPTID NUMBER
DEPTNAME VARCHAR2(10)

SQL> desc student;
Name Null? Type
----------------------------------------- -------- ----------------------------
STDID NUMBER
NAME VARCHAR2(15)
DEPTID NUMBER

After describing both table we see both table have a same column name deptid. Now if I perform natural join then tables with same column name is joined.
SQL> select s.name,d.deptname from dept d NATURAL JOIN student s ;
NAME DEPTNAME
--------------- ----------
Rafi CSE
Arju CSE

As both table have same column deptid so deptid is joined.

Now I rename deptid column and see the result. We will notice in that case inner join will be performed.

SQL> alter table student rename column deptid to deptid1;
Table altered.

SQL> select s.name,d.deptname from dept d NATURAL JOIN student s ;

NAME DEPTNAME
--------------- ----------
Rafi EEE
Raju EEE
Arju EEE
Rafi CSE
Raju CSE
Arju CSE

6 rows selected.

As both table don't have same column name so normal join/inner join is performed.
SQL> select s.name,d.deptname from dept d, student s ;

NAME DEPTNAME
--------------- ----------
Rafi EEE
Raju EEE
Arju EEE
Rafi CSE
Raju CSE
Arju CSE

6 rows selected.

SQL> select s.name,d.deptname from dept d CROSS JOIN student s ;


NAME DEPTNAME
--------------- ----------
Rafi EEE
Raju EEE
Arju EEE
Rafi CSE
Raju CSE
Arju CSE

6 rows selected.
Related Document:
-----------------------

Difference between Inner join and Outer join
Joins in Oracle