sql tuning using indexing -...
TRANSCRIPT
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 1 of 38
REPORT ON SQL TUNING USING INDEXING
SUBMITTED BY
SRUNOKSHI KANIYUR PREMA NEELAKANTAN
CIS -798 INDEPENDENT STUDY
COURSE PROFESSOR – Dr.TORBEN AMTOFT
Kansas State University
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 2 of 38
TABLE OF CONTENTS
INTRODUCTION ................................................................................................................................. 4
CREATING AND MAPPING THE PLAN_TABLE ........................................................................... 4
PLAN_TABLE ...................................................................................................................................... 4 PLAN_TABLE COLUMN DESCRIPTION .................................................................................................... 6
EXPLAIN PLAN ................................................................................................................................... 8
EXECUTION PLAN ................................................................................................................................... 8 PRE REQUISITES TO WORK WITH EXECUTION PLAN ................................................................................... 8 ACCESS METHOD IN ORACLE ................................................................................................................. 9 FULL TABLE SCAN ................................................................................................................................... 9 INDEX SCAN ............................................................................................................................................ 9 RANGE SCAN ........................................................................................................................................... 9 JOINS .................................................................................................................................................... 10 NESTED LOOP ........................................................................................................................................ 10 HASH JOIN ............................................................................................................................................. 10 ORDERING OF RECORDS ....................................................................................................................... 12 SORT ..................................................................................................................................................... 12
INDEXING .......................................................................................................................................... 13
WHEN/WHERE TO USE INDEXING ............................................................................................................ 13 TYPES OF INDEXING ............................................................................................................................. 13 B-TREE INDEX ....................................................................................................................................... 13 BITMAP INDEX ....................................................................................................................................... 14 FUNCTION-BASED INDEX ....................................................................................................................... 14 COMPOSITE INDEX ................................................................................................................................. 14 WHEN NOT TO USE AN INDEX ................................................................................................................. 14
SELECTING AN INDEX ................................................................................................................... 15
1. INDEXING ON ‘PRIMARY KEY’ COLUMNS IN TABLES ........................................................................ 15 STEP - 1 CREATE BITMAP INDEX ON PRIMARY KEY COLUMN .................................................................. 15 STEP - 2 REMOVE THE BITMAP INDEX AND USE B-TREE INDEX ON CUID COLUMN OF THE ‘CUSTOMER’
TABLE ................................................................................................................................................... 17 2. INDEXING ON ‘FOREIGN KEY’ COLUMNS IN TABLES ........................................................................ 19 STEP - 1 USING B-TREE INDEX IN BOTH ‘PRIMARY KEY’ AND ‘FOREIGN KEY’ ......................................... 19 STEP - 2 USE B-TREE INDEX ON A ‘PRIMARY KEY’ AND BITMAP INDEX ON A ‘FOREIGN KEY’. ................. 21 3. FUNCTION BASED INDEX (FBI) ......................................................................................................... 22 STEP - 1 EXECUTING QUERY WITHOUT FUNCTION BASED INDEX ............................................................. 22 STEP - 2 EXECUTING QUERY WITH FUNCTION BASED INDEX ................................................................... 24 4. COMPOSITE INDEX ........................................................................................................................... 25 STEP - 1 EXECUTING THE QUERY WITHOUT COMPOSITE INDEX ............................................................... 25
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 3 of 38
STEP - 2 EXECUTING THE QUERY WITH A COMPOSITE INDEX ................................................................... 26 EXAMPLES FOR FUNCTION BASED AND BITMAP INDEX ............................................................ 29 BITMAP INDEX ....................................................................................................................................... 29 FUNCTION-BASED INDEX ....................................................................................................................... 31
INDEX MAINTENANCE ................................................................................................................... 32
STEPS TAKEN TO MONITOR INDEX ....................................................................................................... 32 MONITORING INDEX USAGE ................................................................................................................. 32 1. VIEW V$OBJECT_USAGE .............................................................................................................. 32 2. MONITOR INDEX ................................................................................................................................ 33 MONITORING INDEX SPACE ................................................................................................................. 35 1. COMPUTING STATISTICS ..................................................................................................................... 35 2. VALIDATE INDEX ............................................................................................................................... 35 3. CHECK THE INDEX_STATS VIEW ..................................................................................................... 36 CONDITIONS TO DROP AN INDEX .......................................................................................................... 38
REFERENCE ...................................................................................................................................... 38
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 4 of 38
SQL TUNING USING INDEXING
INTRODUCTION
There are many applications that interact with database to store and retrieve information from
tables. Data storage and retrieval is done by issuing SQL commands to that particular table and
the time taken to store/retrieve the data determines an application’s efficiency. SQL tuning using
indexing is one way to improve an SQL queries performance. The following sections are
identified in this report to improve a query’s performance,
An explain plan in Oracle is used to see how a query is executed to retrieve data
To know about various index types and its usage
Identify the effectiveness of various indexes
To monitor and improve performances of stale/unused indexes
CREATING AND MAPPING THE PLAN_TABLE
PLAN_TABLE
When an SQL query is run, Oracle prepares an execution plan for that query to retrieve the
result. Explain plan statement requires a plan_table to store the explanation of the query in the
form of queries. The plan_table can be created locally for individual schema.
Step 1 - Oracle package come with ‘UTXPLAN.SQL’ in the $ORACLE_HOME/rdbms/ admin
directory. I have used this script to create the plan_table in my schema
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 5 of 38
Step 2 – Logged in SQL plus with my username and ran this script and the plan_table was
created under ‘SRUNOKPN’ schema.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 6 of 38
PLAN_TABLE column description
Statement ID – This is used to identify the SQL statements which I have run. Since I have
created a plan_table under my schema the statement ID is set to take my username for every
SQL statement I run
Timestamp – gives the date/time when the SQL query was executed.
Remarks – Comments on the SQL statements can be updated after executing the query
Operation – The first row created for a statement will be either one of the following CRUD
operation (i.e. whether it’s a select, update, delete or insert operation). The other rows few rows
can be ‘Sort’, ‘Index’, ‘Table access’ depending on the access that is being performed on the
SQL query.
Option – The value in this field largely depends on the operation performed. It can be either full
table scan or range scan
Object_owner – Specifies the table owner name. We can access data from other schemas
provided we have access privileges to other schema.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 7 of 38
Object_name – name of the table or view used in this SQL query
Optimizer – current option chosen by the database based on the SQL query
Cost- The database can choose ‘Cost-based optimizer’ when given a choice but it depends on the
resources utility for retrieving the data. (The resources here are the CPU_COST & IO_COST). If
the optimizer chooses ‘Rule-based optimizer’ then the value of this field will be 0’.
CPU_COST – Number of machine cycles to determine the cost
IO_COST – Number of datablocks accessed to retrieve the data
Step 3 – Map the plan_table to ‘SRUNOKPN’ schema, so that when ever a query is run and
explain plan command is issued all the rows will be inserted in this table found under this
schema.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 8 of 38
EXPLAIN PLAN
EXECUTION PLAN
To run an SQL query, oracle performs various operations in the background i.e. to retrieve the
result directly from the database or makes it ready for the user to execute the SQL or does both.
This type of method which Oracle employs is called the ‘Execution plan’. The execution plan’s
result is stored in plan_table (SRUNOKPN.PLAN_TABLE). Each rows inserted into this table
can be different, i.e.
It can specify the table access method for the given SQL statement i.e. either by full table
scan or Index –scan (if the column given in the condition is indexed) or Range –scan (if there
are no index or if it couldn’t find the appropriate index to retrieve the data)
Join method used for retrieving data from multiple tables
The way in which ordering is performed on a dataset which can be sort or filter operation
Pre requisites to work with execution plan
To make sure we have access permissions to read and edit the table contents which the SQL
statements accesses.
To make sure that we can insert rows into plan table if it is under a different schema and also
access to view the output from plan_table
I am using TOAD to view the results of ‘Explain plan’
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 9 of 38
ACCESS METHOD IN ORACLE
Full table scan
Oracle retrieves records after accessing the entire table. Fig.1 shows 2 things, (1) that a full-
table scan is done on the ‘CUSTOMER’ table in ‘SRUNOKPN’ schema to retrieve the necessary
records in the table (access method). (2) The cost for running the query is NULL which means
that the optimizer has used ‘Rule based optimizer’ to execute this query. Usually full-table scan
is not advisable for large tables.
(Fig. 1 – Full table scan result which shows that all the rows in ‘customer’ table has been
accessed to return the result set)
Index scan
Indexing is usually done on a column that is unique or often used. By doing this on such columns
it enable SQL statement to retrieve data faster. It is one of the efficient methods used in
improving the performance of the query
Range scan
The data is accessed by using row id, which is a pseudo column in Oracle and every row in a
table is associated with a unique id. A row id gives granular detail about the location of a row i.e.
it leads to the location of the file, the block & finally to the slot where the data exists. If the row
id is know, then this access method is the quickest way of retrieving data
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 10 of 38
JOINS
Nested loop
Nested loop is used by SQL statements that access multiple columns from different tables to
retrieve results. When two tables are used in SQL statement, then all the rows in the first table
satisfying the given ‘where’ condition is returned and then the result of the first table probes the
second table to return result satisfying each row in the first table. The result for the second table
is obtained by performing either full table scan (FTS) or by index. An example of the nested loop
is given by the following SQL statement which returns all the customers who are both in
customer and citation table.
select cuid, cuname,pc_number
from customer, citation
where cuid = pc_cuid
and substr(pc_number,1,2) = '07';
(Fig. 2 shows the two tables that are nested i.e. customer & citation table. ‘CUID’ is the primary
key for customer table and ‘PC_CUID’ is the foreign key in citation table)
Understanding the explain plan for the above diagram,
Nested loops means there exists a join condition between the citation and customer table
Table access full (SRUNOKPN.CITATION) means full table scan is done for citation in
SRUNOKPN schema
But the customer table is accessed returns records based on the unique value of the table. In
customer table ‘CUID’ field is the primary key which is always unique and the customer
table retrieves distinct row when using this unique column and the ‘Table access by index
rowid (SRUNOKPN.CUSTOMER)’ means the table returns the result set based on the
records returned by ‘INDEX UNIQUE SCAN’ which is the ‘CUID’ field
Hash Join
When a large table is joined to a small table, the efficiency in retrieving the might be a big
question. To avoid such situations Oracle’s hash join is used. When the SQL statement is
executed, hash join takes every single row of the first table (small table) and produces a hash
value for each row using hash algorithm and stores it in a hash table. It performs the same action
for the second (larger table). Then it looks for a matching hash value for the large table with the
previously generated hash value of the small table, if it matches then the result is produced. For
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 11 of 38
example, the following SQL statement returns all customers who have received citations. A
customer can receive ‘n’ number of citation. So there exist ‘one-to-many’ relationships between
these tables.
select /*+ use_hash(customer)*/ cuname, pc_number
from customer, citation
where cuid = pc_cuid;
(Fig. 3 Shows the Hash join between two tables)
Understanding the explain plan for the above diagram,
Table access full (SRUNOKPN.CUSTOMER) means full table scan is performed on
customer table.
Table access full (SRUNOKPN.CITATION) means full table scan is performed on citation
table and all the citations matching the customer records in the customer table is returned as
the result.
Hash join specifies that the small table in this query ‘customer’ table joins the large table i.e.
‘citation’ table.
The hash join can be used only if the ‘hash_join_enabled’ feature is set TRUE in init.ora file. The
following figure shows that that property has been set true in my init.ora file.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 12 of 38
ORDERING OF RECORDS
There are various operations to perform ordering operations, i.e. either by sort or filter
Sort
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 13 of 38
(Fig 5 shows that the records returned are ordered based on the sort operation. Sorting
operation should not be used for large tables because it affects the performance of a query.)
INDEXING
Indexing is one of the best ways to improve the performance of a query. Index is an access to
point to rows of data using which the result set of a query is retrieved faster. This property can be
utilized to the maximum if the appropriate index is used and the improvement is visible only
when the correct columns are indexed.
When/where to use indexing
The columns that have high selectivity(i.e. often used in the ‘where’ clause) are indexed
Columns that have high cardinality(i.e. unique data) needs to be indexed
Primary key columns are automatically indexed. But to improve the performance in those
tables additional indexing can be done (as one table can have more than one index provided it
doesn’t affect the performance of other index)
Foreign key columns needs to be indexed which are often used in constraint checks.
TYPES OF INDEXING
There are various types of indexes that can be used based on the query’s performance. This
section discusses about the index types.
B-Tree index
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 14 of 38
This index is in tree structure which has a root node and all the values that are greater than the
root node values are found on the right side and the values less than the root node are found to
the left side. Each data is associated with a value (rowid) and the index looks up for that value to
retrieve the result set of the query. Whenever a basic index is created without specifying the type,
then a B-tree index is normally created. These are usually used in the columns with high
cardinality and high selectivity. Since the entered data is always in specific order sorting is
quickly performed on a large amount of data. When a primary key is created an index is
automatically created and this index type is B-Tree index.
An example of B-Tree index column can be department id.
Bitmap index
Bitmap index are created for the columns with less unique value. The bitmaps are often
compressed and stored to save table space for indexing. They are easily decompressed to retrieve
the necessary values. Since the bitmap indexes are compressed, it is important to create these
indexes on columns that have lesser CRUD operations performed on it.
A popular example of bitmap index columns is the gender column with values M/F.
Function-based index
Function based index are an advanced way of performing indexing. In traditional method only
the columns are indexed, but with this type even an expression, SQL function can be used as
index for faster data retrieval. This index type can be used for more powerful sorts like case-
insensitive sorts. But unlike other indexes FBI can be used only by cost-based optimizer (CBO),
because Oracle requires statistics to use this index. Analyze tables/index should be done before
using the index. No aggregate functions can be used in FBI. These index columns can work only
with non-null values. Though there are more restrictions in using this index, when correctly
indexed they tremendously improve a query’s performance.
An example of function-based index is to change the mixed case columns (like aBCDefGh)
to either lower/uppercase word before sorting.
Composite index
Composite index are created by joining two or more columns. The indexing can be done on those
columns that are often used together to improve the performance. Also columns that are used in
join conditions can be used in composite index.
When not to use an index
Indexing should not be done on columns that have lot of null values.
Number of indexes per table should be kept minimal, otherwise it causes additional index
overhead and can worsen a query’s performance.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 15 of 38
Columns that are very frequently updated should not be indexed.
Small tables need not have indexes as it would retrieve data faster without an index.
Based on the processing time using ‘Explain plan’ or SQL trace facility it can be decided if a
column needs to be indexed or not.
SELECTING AN INDEX
There are certain conditions that need to be satisfied before indexing the columns. Some of these
conditions and index analyzed and used in the columns
1. INDEXING ON ‘PRIMARY KEY’ COLUMNS IN TABLES
When the primary key of a column is selected, that column automatically uses B-tree index. This
is because the B-tree index is used on the columns with unique values and has the entered value
in an ordered list. But in this case study, B-tree indexing can be removed and Bitmap index can
be used to compare the differences.
Step - 1 Create Bitmap index on primary key column
Here the ‘CUID’ is the primary key column of the ‘CUSTOMER’ table. To perform the
experiment, remove B-tree index from the column ‘CUID’ of the ‘CUSTOMER’ table and create
Bitmap index on the same column. The differences can be noticed through ‘execution time’ and
‘explain plan’
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 16 of 38
(Fig – 1(a) shows the index ‘CUST_EMPNO_BMX’ properties and it shows that the column
‘CUID’ is using Bitmap index, which is the primary key of the ‘CUSTOMER’table)
After creating a ‘Bitmap’ index on CUID, a simple query is run to retrieve the row satisfying the
given condition.
The result of the execution time and explain plan for the SQL query is given in fig 1(b) & 1(c).
Query – 1
select * from customer where cuid = 6112;
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 17 of 38
(Fig-1(b) the highlighted line in the fig shows the execution time for the Query - 1)
It has actually taken 16 msecs to run the Query – 1 using Bitmap index.
(Fig-1(c) shows the explain plan for Query - 1)
It has made use of the bitmap index ‘CUST_EMPNO_BMX’ for retrieving the result. Also the
cost for executing the Query-1 is shown because Oracle uses Bitmap index in its execution plan
only after a table is analyzed.
Step - 2 Remove the Bitmap index and use B-tree index on CUID column of the
‘CUSTOMER’ table
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 18 of 38
(Fig-1(d) shows the B-tree index ‘CUID’ on the table ‘CUSTOMER’)
Since the value in this column is unique, I have marked it as a primary key. When a primary key
is selected, a B-tree index is automatically created on that column. Fig 1(e) & 1(f) shows the
explain plan & execution plan for the B-tree index.
(Fig-1(e) shows the explain plan for B-tree index on ‘CUID’ column after executing Query - 1)
The explain plan shows that Oracle has made use of CUID index in retrieving the result that
matches the given condition in Query-1.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 19 of 38
(Fig-1(f) shows the execution time for Query – 1 after using B-tree index)
The execution time for Query-1 using B-tree index is 15 msecs unlike Bitmap index for the same
query which took 1 msec extra to retrieve the same result.
From step (1) & (2)’s execution time and explain plan, the following reasons are inferred and a
decision is made based on these reasons,
Each record in the table is unique and is associated with a unique rowid. When a query is
executed the B-tree index looks up on the ‘rowid’ and retrieves the result. Whereas in Bitmap
index, the values are not unique and so are stored in compressed manner i.e. in bitmaps. So when
a query is executed the Bitmap index has to first decompress the bitmap data and convert it into
rowids which are usually used by Oracle to locate data. This conversion will take time to retrieve
the records with unique value.
Another reason to use B-tree index is because these column values will be used in join
conditions/ constraint checks. The execution time is more important in such situations. Also the
data is stored in an ordered manner and so ‘ORDER BY’ function produces more efficient
results. So it is good to use B-tree index on primary key which will retrieve data in an ordered
and efficient manner.
2. INDEXING ON ‘FOREIGN KEY’ COLUMNS IN TABLES
Foreign key columns are indexed to improving the performance of join condition. The foreign
key can use either B-tree index or Bitmap index. The differences in using both indexes are
explained below. The ‘CUID’ column in the ‘CUSTOMER’ table is the primary key column and
‘PC_CUID’ in the ‘CITATION’ table is the foreign key column.
The following query is used in testing this process,
Query - 2
select * from customer, citation
where cuid = pc_cuid and p_cuid = 6112;
Step - 1 Using B-tree index in both ‘Primary key’ and ‘Foreign key’
Primary key will have B-tree index, because it has already been experimented and decided. In
this step an experiment is done on ‘Foreign key’ using B-tree as its index. The execution time is
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 20 of 38
used to identify the time taken to run a query and explain plan is used to check if Oracle has used
the index in retrieving the result or not.
(Fig – 1(g) shows the execution time for Query - 2 after a B-tree index is created on ‘Foreign
key’)
After indexing the ‘Foreign key’ and using the column in constraint checks, it has taken 32msecs
for Oracle to retrieve 392 rows.
(Fig-1(h) shows the explain plan Query - 2 after indexing ‘PC_CUID’)
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 21 of 38
Here the explain plan shows that the index unique scan has been done on the customer table as
the ‘CUID’ column has unique value and also it’s the primary key column of that table. This
means that Oracle looks into the index CUID and retrieves the rowids associated with the table
rows. Whereas an index range scan is done on the pc_cuid column of the citation table, this is
because the pc_cuid column returns more than one row for the given condition. As the citation
table has non-unique values and it is the subset of customer table.
Step - 2 Use B-tree index on a ‘Primary key’ and Bitmap index on a ‘Foreign key’.
The Bitmap index is normally used in columns with non-unique or null values. Since the
PC_CUID is a foreign key column, Bitmap index is used in this column. As a customer can
receive ‘n’ number of citation and each of this citation are stored in the citation table with cuid as
the reference number. The experiment is analyzed using explain plan and execution time.
(Fig-1(i) shows the execution time after using Bitmap index on PC_CUID column)
After using Bitmap index on PC_CUID column, the execution time has reduced to half, i.e. with
Btree index it took 32 msecs to execute the query whereas with Bitmap index it has actually
taken only 16 msecs to retrieve the same result set.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 22 of 38
(Fig – 1(j) shows the explain plan for PC_CUID column with Bitmap index)
The PC_CUID_BMX compresses the data and builds a bitmap. The bitmap are then
decompressed and then converted into rowids which are easily identified by Oracle to retrieve
the result set from citation table.
From Steps (1) & (2)’s execution time it can be said that Foreign keys when using Bitmap
indexes improves performance than using B-tree index.
3. FUNCTION BASED INDEX (FBI)
Function based index are the created on expressions/ functions using the columns of a table. The
value of these functions is stored in the index and is readily used when these functions are used
in a query. For this index a comparative study is done on a query with FBI and without FBI.
Step - 1 Executing query without Function based index
The following query is used to test this index type. The highlighted part of the where condition is
the expression to be used in index. But here in this step the query is run without using the index
and difference is noted
Query – 3
select * from citation
where trunc(to_date('11/13/2008','MM/DD/YYYY')-pc_date_issue) > 500;
This query displays the citations that are older than 500 days as of Nov 13, 2008.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 23 of 38
(Fig-1(k) shows the execution time for Query – 3 to retrieve result without using the function
based index)
It has taken 32 msecs to execute the query without FBI.
(Fig-1(l) shows the explain plan for Query – 3 to run without using function based index)
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 24 of 38
From Fig-1(l) it can be seen that Oracle has performed full table scan to get the result set
satisfying the given expression. Because that the best option it was able to find as the expression
was not indexed.
Step - 2 Executing query with Function based index
In this step an index ‘FNIDX_OVERDUE’ is created for the highlighted expression in the above
given query.
The expression is pre-compiled and the results are stored in index. So whenever an expression is
queried upon, Oracle searches the index and displays the stored values instead of performing full
table scan. An example can be seen in the following explain plan & execution plan,
(Fig-1(m) shows the execution time of Query – 3 after using the function-based index)
After the ‘FNIDX_OVERDUE’ index is created, the execution time of the query is 15 msecs
which is nearly half the time taken without function based index.
(Fig-1(n) shows the explain plan for the Query - 3)
The explain plan shows that Oracle has chose to use the function based index when the indexed
expression is used in the query. Also note that the cost of executing the query appears in this, it
because just like the Bitmap index, Oracle will use function based index only if the table & index
is analyzed.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 25 of 38
Case-1 In one of my business situations I need to get a list of all citations that are more than 250
days old. In this type of situation I can use Function-based index as given above to store all the
citations that satisfy the given condition in an index. By doing this type of indexing, data is
retrieved faster and improves the performance of my PL/SQL script.
4. COMPOSITE INDEX
More than one column can be combined and used as index. This type of indexing is called
composite index. Explain plan and execution time can be used to better understand this type of
indexing.
Step - 1 Executing the query without composite index
The query used in both the steps is given below,
Query – 4
select * from customer
where cuname like 'S%' and cu_pec_id = 12;
(Fig-1(o) shows the execution time for Query - 4)
It has taken 47 msecs to display 19 records without indexing the two columns which are often
used together.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 26 of 38
(Fig-1(p) shows the explain plan for the Query - 4)
The explain plan shows that Oracle has performed full table scan on the customer table to
retrieve the 3 rows satisfying the two conditions i.e. the name should start with the letter ‘S’ and
it should belong to customer group ‘12’ i.e. the Graduate students.
Step - 2 Executing the query with a composite index
Composite index ‘cbi_indx_grp’ is created for the 2 columns that are highlighted in the query
(CUNAME & CU_PEC_ID). The explain plan & execution time will show the difference in
executing the same query with this index.
(Fig-(q) shows the execution time for Query – 4 after creating a composite index)
The execution time shows that it has taken 16 msecs to display the result for the same query
which is used to display 19 records and with the same condition.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 27 of 38
(Fig-(r) shows the explain plan for Query - 4)
Explain plan shows that Oracle has made use of the composite index to check the conditions and
to display the result.
From step (1) & (2)’s execution time and explain plan it can be said that using composite indexes
on columns are used together in checking condition helps in improving the performance of the
query.
Note
A primary key column can be used as one of the columns in composite indexing, but in such
situations Oracle will choose to use B-tree index on the primary column rather than composite
index.
E.g. The CUID and CUNAME columns in the customer table can be used to create another
composite index. The table below shows the index description,
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 28 of 38
(Fig-(s) shows the description of the composite index (CBI_CUID))
The highlighted columns (CUID, CUNAME) are used in the composite index CBI_CUID.
‘CUID’ is the primary key column for the customer table & the existing B-Tree is not removed
for that table.
Now the interpretation of execution plan for the following query is given below,
Query – 5
select * from customer
where cuname like '%LL%' and cuid=5206 ;
When the above given query is executed we expect Oracle to take the composite index to execute
the results as both these columns are combined and indexed. But when the query is run it actually
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 29 of 38
uses the B-tree index on CUID column rather than using composite index. Because a B-tree
indexed column has unique value and retrieves data faster than other types of indexing.
(Fig-(t) shows the explain plan for Query - 5)
EXAMPLES FOR FUNCTION BASED AND BITMAP INDEX
Bitmap index
Bitmap indexes are mainly used in dataware housing. Columns that are used in data analysis
can be indexed with bitmaps.
They work at their best for equality operators
E.g. In my application, at the end of every month I need to get the account receivables for all the
unpaid citations with different statuses. In such situations I can index the PC_STATUS column
in the CITATION table, which in turn will compress all the citations with the same status. When
a query is issued to get a count of all citations based on their citation status and the query used is,
Query - 6 select pc_status, count(pc_number)
from citation
group by pc_status;
(Fig – 1 shows the explain plan for Query -6)
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 30 of 38
The Fig-1 above shows gives the explain plan for the Query-6 Oracle has performed a full table
scan on the table to get the desired result.
(Fig -2 shows the ‘PC_STATUS_BMP’ index creation)
It has actually taken 718msecs to create an index for 110755 rows. The row above index creation
gives the time taken to run Query – 6 and it has actually taken 407 msecs to execute and display
the result.
(Fig – 3(a) shows Query-6 execution time after index creation)
(Fig – 3(b) shows Query-6 explain plan after index creation)
Fig-3(a) shows that it has actually taken 31msecs to execute the same query and Fig-3(b) shows
that Oracle used the index ‘PC_STATUS_BMP’ for executing Query -6
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 31 of 38
Function-based index
Function-based index can be used in queries that returns a value for an expression
E.g. To get a list of customer who have received citation in Manhattan campus and this can be
given by the following query,
Query-7 select * from citation
where substr(pc_number,3,1) = 'M';
(Fig – 4 shows the execution time for Query – 7 before using function-based index)
Query-7 has taken 32 msecs to retrieve the result without function based index
(Fig – 4(a) shows the execution time for index creation and Query-7 execution time)
The highlighted part in red color shows that Oracle has taken 5 secs to create the function based
index ‘PC_NUMBER_FBI’ for 105721 records. 105721 records satisfy the given expression i.e.
they all are manhattan citation. When Query-7 is executed it uses the index PC_NUMBER_FBI
to retrieve the rows which are already stored in the index. The execution time for the same has
reduced by ½ i.e. it has taken only 16 msecs to display the result.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 32 of 38
Note
In the CIATION table, PC_NUMBER is the primary key column (using B-tree index) and has
unique values in that column. When using that column in the conditional field we expect Oracle
to choose PC_NUMBER index but the condition given in Query-7 uses an expression in the
conditional field. PC_NUMBER_FBI is created using the exact same expression and all the row
in that table is precompiled and stored within the index. So when the Query-7 is executed Oracle
prefers PC_NUMBER_FBI than PC_NUMBER index. This can be proved using the explain
plan shown in Fig – 4(b)
INDEX MAINTENANCE
When the CRUD operations are issued on a table, the records are prone to changes and it might
cause overhead to the index associated with the columns of those tables. This usually happens
because each index is associated with a statistics and when the column’s data undergoes changes
the statistics becomes outdated which will make the queries to run slowly that was earlier
running efficiently. Such indices problem can be avoided by keeping track of an index space and
its usage. This section deals with the ways to monitor an index and to maintain its usefulness.
STEPS TAKEN TO MONITOR INDEX
The following steps needs to be done periodically for all the indexes that has been created on the
columns of a table,
The index used in my examples is ‘PC_NUMBER’ which is a B-tree index created on the
column PC_NUMBER in the table CITATION.
MONITORING INDEX USAGE
1. VIEW V$OBJECT_USAGE
This view is helpful when the monitoring of an index starts. The view V$OBJECT_USAGE’
displays the following columns
INDEX_NAME – Name of the index
TABLE_NAME – Table name of the column for which the index has been created
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 33 of 38
MONIORING - It has the Boolean value (YES/NO) to specify if the index as mentioned in
‘INDEX NAME’ column is used or not
USED – This column too has Boolean value (YES/NO) to specify if an index is still used or not
START MONIORING – This column displays the data & time when the monitoring for the index
was started
STOP MONIORING - This column displays the data & time when the monitoring for the index
was stopped
(Fig - 1 shows the initial status of the index ‘PC_NUMBER’)
It can be seen from Fig-1 that monitoring for the index has not yet started, so it is not easy to see
if the index is being used or not.
2. Monitor index
This step is done to start monitoring the usage of an index. It can be invoked by using the
command
ALTER INDEX PC_NUMBER MONITORING USAGE;
(Fig-2 (a) Shows that monitoring has started for the index ‘PC_NUMBER’)
The Fig-2 (a) shows that the monitoring has started but as far as the usage is concerned the index
is still not used, which shows that none of the query has currently made use of the index after the
monitoring has started. The query used in this example is,
Query -8 select * from customer, citation
where pc_cuid = cuid and
pc_number like '08M502133';
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 34 of 38
(Fig – 2(b) shows the explain plan for Query – 8)
The explain plan shows that Oracle has used the index ‘PC_NUMBER’ to retrieve the result
satisfying the condition.
(Fig – 2(c) shows that index PC_NUMBER is used in a query)
Index monitor can be stopped using the command,
ALTER INDEX PC_NUMBER NOMONITORING USAGE;
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 35 of 38
(Fig – 2(d) shows that an index monitor for ‘PC_NUMBER’ is stopped)
Note
An index monitor can be kept ‘ON’ to constantly monitor indexes that are not being used often.
Every time when the ‘MONITOR USAGE’ command is issued for an index, the column values
in the view V$OBJECT_USAGE may be different.
MONITORING INDEX SPACE
When an index is created a space is allotted for each index. Depending on the insertion/deletion
operations on the columns, the space used may vary. Constant watch on index space should be
done to avoid overhead of indexes. The following steps should be done to check the index space,
1. Computing statistics
The index whose space needs to be checked must be analyzed first to estimate the current
statistics and cost of that index. Index PC_NUMBER is used as an example here. The following
command is issued to analyze the index,
analyze table citation compute statistics for table for all indexes for all
indexed columns;
2. Validate index
The index is validated to make sure that the rows in the index are still available in the table. This
validation should be done for foreign key index to ensure that all the rows are present in the
primary key. It also makes sure that the statistics computed by ‘Analyze index’ is current. In our
example, the index ‘PC_NUMBER’ is to be validated using the command given below,
validate index PC_NUMBER;
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 36 of 38
3. Check the INDEX_STATS view
The INDEX_STATS view gives the index space used values. There are many columns in the
views of which few columns are used to determine the space used by an index.
Height – gives the total height of the B-tree index
Blocks - gives the value of the segment that’s has been allocated to the blocks
Name – index name
LF_BLKS – Number of leaf blocks
BR_BLKS – Number of B-tree blocks
Del_lf_rows – Number of leaf rows that has been deleted
Btree_space – Total space allotted for B-tree index
Pct_used – Percentage of space used by the index
(Fig – 3(a) shows the INDEX_STATS view for PC_NUMBER)
The PC_NUMBER is the primary key column for citation table. This view shows that the index
has been created on the PC_NUMBER column. PCT_USED shows a blank column, because
there is no data in the citation table to determine the space occupied by the index. The total space
allotted for B-tree index ‘PC_NUMBER’ is 7996 which can be seen in the column
BTREE_SPACE.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 37 of 38
(Fig – 3(b) shows the values of INDEX_STATS view for the index ‘PC_NUMBER’ after inserting
rows in the citation table)
Now looking at Fig -3(b) shows the space that the index has occupied after inserting the rows in
the PC_NUMBER column. The Btree space allotted for the index has now increased to
42299880 and also the index has used some 59% of the allotted space. This value can be
obtained from PCT_USED column.
Now test the space used by the index PC_NUMBER after deleting 7516 rows from the table.
Follow instructions from Step 1 - step 3 to get the values of the space used by index.
(Fig – 3(c) shows the values of INDEX_STATS view for the index ‘PC_NUMBER’ after deleting
rows in the citation table)
The space allotted for the index is still the same but the space occupied by the index has reduced
by 1% (i.e. from 59% to 58%).
By using the above criteria i.e. by monitoring index usage and space used by index it can be
decided whether to use an index or drop it.
CIS 798 – Report on SQL Tuning using Indexing Srunokshi Kaniyur Prema Neelakantan
Page 38 of 38
CONDITIONS TO DROP AN INDEX
Indexes that are no longer used by Oracle queries or application to retrieve the result can be
dropped
If the performance of a query is not improved by using that index
If the cost of dropping the index is less than retaining the same index
REFERENCE
1) http://download-
west.oracle.com/docs/cd/A87860_01/doc/server.817/a76992/ch13_exp.htm#822
2) http://www.acs.ilstu.edu/docs/Oracle/server.101/b10759/statements_5010.htm
3) http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/data_acc.htm#i7530
4) http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96590/adg06idx.htm#1618
5) http://www.youngcow.net/doc/oracle10g/server.102/b14231/indexes.htm#i1006918