Indexing and
Performance Tuning
--------------------------------
The two most important elements of Performance Tuning are
indexing and buffer size manipulation.
We will work on indexing.
Let us remember what an index does.
Imagine a phone book and you want to find people
by FIRST NAME.
You would have to read the whole book
line-by-line.
Or, you create a list of first names,
and then for every first name a pointer [e.g., see
page 209, line 38]
to where a person of that first name exists in
the
phone book.
This list of first names and pointers is called an
INDEX. If you have an unsorted,
unindexed column,
Oracle reads the data line-by-line. This
is not a good
idea for fast access.
How do I even know that I improved things?
One possible approach is to measure times of executions.
The table people contains 320,000 rows.
SELECT TO_CHAR(SYSTIMESTAMP, 'SSSSS.FF') FROM
DUAL
/
SELECT * from people
/
SELECT TO_CHAR(SYSTIMESTAMP, 'SSSSS.FF') FROM
DUAL
/
The other possibility is that we use
the time returned by SQL Developer.
WARNING: Oracle
does some caching, so the second run
of the same select statement is likely to be
faster.
Also note that sometimes an index actually makes
things slower, because you have first a disk access
to
get the index and then a second disk access to get the
data.
Disk access is the slowest operation of all, the bottle neck.
--------------------------
The importance of good query design:
Consider the table containing the gender and age of
320,000 people. If you wanted to obtain
all the males aged 34 and the table had an index
on gender and an index on age there
would be two possibilities.
* Use the gender index to first obtain
all males
and then go through the result set finding the 34 year
olds
We know there are 320,000 people in the table. If we
used the index to find all males it is fair to say we
would return about 160,000 rows. We would then have
160,000 rows which we have to search in order (one by one)
for 34 year olds.
* Use the age index to first obtain
all 34 year olds
and then search the result set finding the males
Assume people are between 0 and 100.
These will not be equally distributed.
There are many more people aged 34 than people aged 99.
Now VERY approximately we would return about 2% of the rows
(about 6400) which we have to search in order (one by
one)
for males.
So, the second approach is obviously much better.
Use the index that will give you the smallest result set.
----------------------------------------------------------------------
Surprise: Oracle does not HAVE TO use an
index,
even if you create one.
We have to force the system to use index structures.
You can give "hints" to the optimizer.
Hints look like comments INSIDE THE select statement,
starting with a + sign. The FULL hint requires a full
table scan, as opposed to using an index.
==========================================
Bad design, no index.
SELECT *
FROM (
SELECT *
FROM PEOPLE
WHERE GENDER = 'M'
)
WHERE AGE = 34
/
==========================================
Good design, no index.
SELECT *
FROM (
SELECT *
FROM PEOPLE
WHERE AGE = 34
)
WHERE GENDER = 'M'
/
==========================================
create index forgender on
PEOPLE(GENDER)
/
Bad design with index.
SELECT *
FROM (
SELECT /*+ INDEX(
PEOPLE, FORGENDER ) */ *
FROM PEOPLE
WHERE GENDER = 'M'
)
WHERE AGE = 34
/
drop index forgender
/
==========================================
create index forage on PEOPLE(AGE)
/
Good design with index.
SELECT *
FROM (
SELECT /*+ INDEX(
PEOPLE, FORAGE ) */ *
FROM PEOPLE
WHERE AGE = 34
)
WHERE GENDER = 'M'
/
drop index forage
/
Conclusion: