0% found this document useful (0 votes)
46 views10 pages

Index and Partitioning

The document provides instructions and examples for creating indexes, index organized tables, partitioned tables, and bitmap indexes in Oracle based on a database schema for managing nurse staffing at hospitals. It describes creating indexes on columns that will be frequently joined or selected on. An index organized table is created for the UKCC table where access will be primarily through the primary key. The availability history table is partitioned into 12 monthly partitions. A bitmap index may improve queries that select a large number of rows based on low to medium cardinality columns like the allocated flag.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views10 pages

Index and Partitioning

The document provides instructions and examples for creating indexes, index organized tables, partitioned tables, and bitmap indexes in Oracle based on a database schema for managing nurse staffing at hospitals. It describes creating indexes on columns that will be frequently joined or selected on. An index organized table is created for the UKCC table where access will be primarily through the primary key. The availability history table is partitioned into 12 monthly partitions. A bitmap index may improve queries that select a large number of rows based on low to medium cardinality columns like the allocated flag.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 10

Oracle Indexing and Partitioning Tutorial

The tutorial database


The examples used here are based around a system for managing the use of Bank Nurse Staff at
hospitals.
In essence, it tries to match nurses with temporary vacancies on a shift on a ward. For these examples
you will also need to know that each nurse has a unique identifier called a UKCC number, and that
nurses will have grades and specialisms. Requirements can be for a minimum grade and/or specialism,
or just for any old nurse. The tables used are described in the diagram below.

Trust

Hospital

Ward

Shift

Specialism

Nurse

NurseSpecial

Requirement

NOTES for completing the tutorial:


1.
2.
3.
4.
5.

You MUST use SQLPLUSW or SQLPLUS, NOT iSQL


Do NOT save this word document locally: the links will not work if you do.
SQLPLUS will object if you are running your scripts from a folder which has spaces in the
path. For example: F:\Advanced Database\testscripts\ You are advice to create a folder off
your F:\ root, or in MyWork.
To follow the examples you will need to create the above tables in your own schema. To do
this, download: ibsmsdata.zip , then make sure all the scripts in the ibsmdata.zip file are
extracted into the same directory before you start.
You only need to run create_tables. Look at the script using an editor to see what it does,
particularly at the end. As a sensible rule, you should always read and understand other
peoples scripts before running them.

Tip for running Scripts: If text files are given an extension of sql (in lower case) e.g. myfile.sql, you
can execute the file by typing @ filename or RUN filename at the sql prompt. Some scripts must be run
like this, rather than by cutting and pasting from an editor. To have SQLPLUS be aware of the folder
you are working from for the rest of the session, use File, Open and open the CREATE_TABLES.sql
script. From now on, SQLPLUS will automatically include the folder in its search paths.

Indexing The Obvious


Your first task is to establish which columns need indexing. You can see in the create script that one
index has already been created:
create index i_nurses_name on Nurses(Sname,Fname) ;
This composite index is required as many queries against Nurse will be based upon name, rather than
PersonID or UKCCNo.

Rule of Thumb:
Add secondary index on attributes that are involved in selection or join criteria.

Activity 1
You have been informed that the following columns will be used extensively in joins when user reports
are run:
Table

Column(s)

Requirements

Grade

Nurses

GradeID

You should create an index on each of these.

Rule of Thumb:
Create an index if you frequently want to retrieve less than 15% of the rows in a large table

Activity 2
Requirements will grow to be a very large table, potentially running to 100,000 rows and in the future
it will need to be actively archived. It will suffer from a heavy load of concurrent INSERTs, UPDATEs,
and DELETEs. However, for the most part, queries against it will only return Requirements for a
particular Ward Shift on a particular day, often just a few rows. You should therefore create a composite
index on the WardShiftID and ReqDate.

Learning Points
In the activities you have create both single column and composite indexes.
You have created indexes on columns because your research into potential usage has indicated
candidate indexes. Once live, you will need to continue to monitor these indexes to see if they are
effective.

Discovering Foreign Keys (FK) without Indexes on child table


Oracle automatically generates indexes for Primary Keys, but if you have set up a relationship, it does
not automatically create an index. There will be occasions, such as if the child table is only very small,
when this may be appropriate. However, it would be nice if we could automatically check to see which
FKs are missing indexes.
This is where a script comes in handy. The one we build below reports all such potential problems. It
uses three system generated views:

USER_CONSTRAINTS, which contains information about all the constraints you own
USER_ CONS_COLUMNS, which is the many end of the 1-many with USER_CONSTRAINTS
and lists the columns referred by each constraint.
USER_ IND_ COLUMNS, which contains information on all the indexes you own

The steps we will need to take are:


1.
2.

Establish what constraints we have by generating a set from some SQL


Do some set arithmetic to remove from that set any already existing indexes.

Copy and paste the code below and paste it into your SQLPLUS> prompt:
SELECT ucc.constraint_name||uc.Table_Name||'('||ucc.column_name||'['||ucc.position||'])'
"Missing Index"
FROM user_cons_columns ucc, user_constraints uc
WHERE uc.constraint_name = ucc.constraint_name
AND uc.constraint_type = 'R';
Key elements of this code are:
The use of || to concatenate characters
The naming of a column "Missing Index"
The two contraint tables are equi-joined on contraint_name
Contraint Type of 'R' is row level constraint.
Make sure you understand this code before building on it.

Next, lets discover the indexes already in place. Copy and paste:
SELECT table_name, column_name, column_position
FROM user_ind_columns ;
Examine the output. You should be able to see the indexes we have already created.
So the output from this needs to be subtracted from the output of the earlier code. To accomplish this
we need to use the MINUS SQL set manipulator. Try this:
SELECT ucc.table_name, ucc.column_name, ucc.position
FROM user_cons_columns ucc, user_constraints uc
WHERE uc.constraint_name = ucc.constraint_name
AND uc.constraint_type = 'R'
MINUS
SELECT table_name, column_name, column_position
FROM user_ind_columns ;

Finally, in an attempt to make this output more readable, we use the IN operator to test for membership
of that set, and whilst we are at it, ORDER the output.

SELECT ucc.constraint_name||uc.Table_Name||'('||ucc.column_name||'['||ucc.position||'])'
"Missing Index"
FROM user_cons_columns ucc, user_constraints uc
WHERE uc.constraint_name = ucc.constraint_name
AND uc.constraint_type = 'R'
AND (ucc.table_name, ucc.column_name, ucc.position)
IN
(SELECT ucc.table_name, ucc.column_name, ucc.position
FROM user_cons_columns ucc, user_constraints uc
WHERE uc.constraint_name = ucc.constraint_name
AND uc.constraint_type = 'R'
MINUS
SELECT table_name, column_name, column_position
FROM user_ind_columns)
ORDER BY ucc.column_name, ucc.position;

Activity 3
Now use the information your script provides to add indexes to appropriate columns. The HOSPTAL
table is considered too small to warrant an index.

Learning Points
We have seen how Oracle provides useful internal VIEWS, such as USER_CONSTRAINTS, and we
have used their output to help us search for candidate indexes.

Index Organised Table (IOT)


Rule of Thumb:
Broadly speaking, any table that is frequently searched and accessed almost exclusively via the
primary key is a candidate for IOT
The Nurse table contains a field called UKCCNo. You are told that UKCC information for all UK
nurses is to be stored within your database. It will be a one-to-one relationship with Nurse. UKCCNo
because you need to allow an external agency access to the UKCC data, it is therefore decided that the
tables should remain separate:

Nurse

UKCC
UKCCNo (text)
ExpiryDate (date)
IssuingAgentID (integer)
Notes (large text)

UKCC will normally be accessed either as a full table scan (to populate look-up tables) or via the
UKCCNo. This might make it a candidate IOT table.

Activity 4
Write and run a script that creates the UKCC as an IOT with "Notes" defined as a CLOB and placed in
an overflow segment. Use the template below to help you with the script:
CREATE TABLE xxxxxxx
(
cols.
CONSTRAINT contraintname PRIMARY KEY (cols )
)
ORGANIZATION INDEX
INCLUDING cols OVERFLOW ;

Learning Points
We have reviewed one particular time when an IOT might be appropriate. The performance testing we
do on another day will be the prime indicator of whether this is a good decision.
You have used Oracle's extension to the standard CREATE TABLE syntax to create an IOT.

Partitioned Table
Rule of Thumb:
If rows may be divided into a series of key ranges, such as ones based on date, partitioning will
enable the effect of striping the data across several disks, speeding up access to the data by allowing
parallel reading to occur.
The other side to the requirements-availability equation is that a nurse will make known what dates and
times she is available for work. This information needs storing in a table. Once the current needs are
met, this information is kept for reporting purposes. You are asked to create the AvailabilityHistory
table as a Partitioned table to store this history. There should be 12 partitions, one for each month of
this year. Allocated works in the same way that it does in Requirements, but will not get updated much
once the data is in AvailabiltyHistory.

Nurse

AvailabilityHistory
PersonID
AvailDate
AvailaStartTime
AvailEndTime
Allocated

Activity 5
Write and run a script that creates the AvailabilityHistory as an Partitioned table. Use the template
below to help you with the script:
CREATE TABLE xxxxx
(
column info
)
PARTITION BY RANGE (range cols)
(
PARTITION Jan03 VALUES LESS THAN ( To_Date ('01-Feb-2003', 'DD-MON-YYYY') ),
.
);

Learning Points
We have reviewed one particular time when Partition may be appropriate. The performance testing we
do on another day will be the prime indicator of whether this is a good decision.
You have used Oracle's extension to the standard CREATE TABLE syntax to create a Partitioned Table.

Bitmap Indexes
Rule of Thumb:
Bitmap indexes can substantially improve performance of queries in which the individual predicates on
low- or medium-cardinality columns select a large number of rows.
You are advised that the following query will be commonly run to discover which requirements have
yet to be filled. Allocated is a boolean column which will always be set to zero when a row is created,
and updated to the value 1 when the shift has been filled:
Select reqid from requirements
where allocated = 0 ;

Activity 6
You are asked to create the bitmap index that could speed this query up. Use the on-line manual to
discover the syntax required.

Activity 7
Have you created the bitmap index in Activity 7? Well, think a little bit more about what you are being
asked to do:
You have been given some information about the Requirements table earlier in this tutorial that should
make you advise against a bitmap index in this circumstance. What is that information? And which
column in which table probably would be an ideal candidate for a bitmap?

Learning Points
We have reviewed one particular time when a bitmap index may be appropriate. The performance
testing we do on another day will be the prime indicator of whether this is a good decision. We have
also learned that we always need to question the suitablility of indexes in each particular context.
You have used the online manual to discover the syntax for creating a bitmap index.

Activity Solutions
Activity 1
create index i_nurses_grade on Nurses(GradeID) ;
create index i_requirements_date on Requirements(Grade) ;

Activity 2
create index i_requirements_shift on Requirements(WardShiftID, ReqDate) ;

Activity 3
create index i_nursespec_fk on Nursespecial(SpecialismID) ;
create index i_wardshift_fk on Ward_Shifts(HospitalID, WardID) ;

Activity 4
CREATE TABLE UKCC
(
UKCCNo VARCHAR2(10),
ExpiryDate DATE,
AgentID Integer,
UKCCNotes CLOB,
CONSTRAINT PK_ukcc PRIMARY KEY (UKCCNo)
)
ORGANIZATION INDEX
INCLUDING UKCCNotes OVERFLOW ;

Activity 5
DROP TABLE AvailabilityHistory ;
CREATE TABLE AvailabilityHistory
(
PersonID Integer PRIMARY KEY,
AvailDate DATE NOT NULL,
AvailaStartTime DATE,
AvailEndTime DATE,
Allocated INTEGER default 0
)
PARTITION BY RANGE ( AvailDate)
(
PARTITION Jan03 VALUES LESS THAN ( To_Date ('01-Feb-2003', 'DD-MON-YYYY') ),
PARTITION Feb03 VALUES LESS THAN ( To_Date ('01-Mar-2003', 'DD-MON-YYYY') ),
PARTITION Mar03 VALUES LESS THAN ( To_Date ('01-Apr-2003', 'DD-MON-YYYY') ),
PARTITION Apr03 VALUES LESS THAN ( To_Date ('01-May-2003', 'DD-MON-YYYY') ),
PARTITION May03 VALUES LESS THAN ( To_Date ('01-Jun-2003', 'DD-MON-YYYY') ),
PARTITION Jun03 VALUES LESS THAN ( To_Date ('01-Jul-2003', 'DD-MON-YYYY') ),
PARTITION Jul03 VALUES LESS THAN ( To_Date ('01-Aug-2003', 'DD-MON-YYYY') ),
PARTITION Aug03 VALUES LESS THAN ( To_Date ('01-Sep-2003', 'DD-MON-YYYY') ),
PARTITION Sep03 VALUES LESS THAN ( To_Date ('01-Oct-2003', 'DD-MON-YYYY') ),
PARTITION Oct03 VALUES LESS THAN ( To_Date ('01-Nov-2003', 'DD-MON-YYYY') ),
PARTITION Nov03 VALUES LESS THAN ( To_Date ('01-Dec-2003', 'DD-MON-YYYY') ),
PARTITION Dec03 VALUES LESS THAN ( To_Date ('01-Jan-2004', 'DD-MON-YYYY') )
);

Activity 6
drop index i_alloc ;
create bitmap index i_alloc on Requirements(Allocated) ;

Activity 7
From the information in Activity 2:
"[the Requirements table]..will suffer from a heavy load of concurrent INSERTs, UPDATEs, and
DELETEs."
This makes the column unsuitable for a bitmap index. The Allocated column in AvailabilityHistory,
however, is a more likely candidate as it will seldom be updated.

You might also like