6
Healthy Code May 2014 20 Article INDEX!=

Db performance optimization with indexing

Embed Size (px)

DESCRIPTION

Optimizing query with index

Citation preview

Page 1: Db performance optimization with indexing

Healthy Code May 201420

Article

INDEX!= FASTER ACCESS

Page 2: Db performance optimization with indexing

Healthy Code May 2014 21

INDEX!= FASTER ACCESS

Ankit Kumar Katiyar & N.S.Sekar

One of the frequently encountered solutions that application developers are offered, while dealing with performance issues with the

oracle database is: “create an index on that column”. This may enhance the performance in some cases if you know your index well enough. However this can actually degrade or not have any significant impact on the SQL performance in the application at all. Therefore it’s important to be aware of the behavior of index if you want to leverage its true potential. We have identified a bunch of issues while working with index in Oracle and discussed them in this article.

Here’s a list of concerns raised by developers and our response to them.

Concern #1:

I have created an appropriate index on particular column. But why is the query engine not picking up the index?

This may happen due to bad or incomplete statistics. In the absence of statistics, the optimizer (Cost based optimization) may choose a full table scan (FTS) as compared to indexed access.

Recommendations:

Prior to testing queries, just make sure you re-analyze the table and index with dbms_stats. This provides the optimizer with good metadata.

You can use the following queries to check the last analyzed status.

x� ������� �����ř� �����ɏ����ř� ����ɏ��������ř� ���ɏ����ř� ������ɏ����� ��������ɏ������� ������ ������ ʰ� ŧʳ�����ʴŨ� ���������ɏ����� ʰ� ŧʳ�����ɏ����ʴŨ� ������ �������ɏ��������Ś

x� ������������ř������ɏ����ř������ɏ����ř�����ɏ��������ř� ���ɏ����ř� ������ɏ�������������ɏ��������������������ʰ�ŧʳ�����ʴŨ�����������ɏ�����ʰ�ŧʳ�����ɏ����ʴŨ���������������ɏ��������Ś

You can use the following queries to execute the dms_stats procedure to analyze objects.

x� ����� ����ɏ�����Ŝ������ɏ�����ɏ�����ſŧʳ������ʴř�ŧʳ�����ɏ�����ʴŨƀŚ

x� ����� ����ɏ�����Ŝ������ɏ�����ɏ�����ſŧʳ�����ʴŨř�ŧʳ�����ɏ�����ʴŨƀŚ

Concern #2:

I have created an appropriate index on a particular column and I have also verified the earlier step discussed in Concern#1. I still see that oracle is not using that index.

This may happen if the number of rows in that table is less or your query is returning almost all the data in a table.

Recommendations:

If table is small that it can be read in a single I/O call, then a full table scan of table might be cheaper than an index range scan. Single I/O call can be defined by

Page 3: Db performance optimization with indexing

Healthy Code May 201422

DB_FILE_MULTIBLOCK_READ_COUNT parameter and value defined by blocks.

If your query is returning the majority of the data in a table, then a full table scan is probably going to be the most efficient way to access the table and optimizer may choose to decide that it would be more efficient not to use the index.

Concern #3:

I have created proper B-Tree Index on the particular column and have also analyzed the table and index. I still don’t find oracle using that index.

Oracle B-TREE Indexes can surely help in improving the query performance provided there is optimal selectivity on that column. The ratio of the number of distinct values in the indexed column/columns to the number of records in the table represents the selectivity of an index. Ideal selectivity is 1 in case of primary key and unique key.

While optimizing, oracle takes a decision of choosing an index based on I/O. As discussed earlier, if the query is returning the majority of the data in a table, then a full table scan is probably going to be the most efficient way to access the table.

Recommendations:

x� We should create indexes on tables that are often queried for less than 15% of the table’s rows. This value may be higher in situations where all data can be retrieved from an index, or where the indexed columns can be used for joining to other tables.

x� Please check if you have right index on that column. In other words, in oracle while standard B-tree indexes are most effective for columns containing a high number of different values (good selectivity), bitmapped indexes are most appropriate for columns with a limited number (poor selectivity) of possible values.

x� In general, B-tree indices are good for OLTP and Bitmapped indices are good for OLAP systems. Factor in your usage, prior to creating the index.

Concern #4:

I have a query

ũ�������Ƌ�����������������������������ŧʩ�����ʩŨŪŜ�

Page 4: Db performance optimization with indexing

Healthy Code May 2014 23

The query engine is still not using the index.

If you are using the SQL “like” clause then it can be tricky because the wildcard “%” operator can invalidate the index.

Recommendations:

x� STRING% will do INDEX RANGE SCAN data because optimizer knows where the string gets started.

x� % STRING will do the INDEX FULL table because LIKE expression that starts with a wildcard.

x� %STRING% will perform the FULL table scan because optimizer doesn’t know from which letter the String get started.

Concern #5:

I have a query,

ũ�������������ſƋƀ������������������������������Ū��

I also have a proper index on id column. Why is the query engine still not using the index?

If you have got a WHERE clause which contains something like “id is null” then query engine will always perform the full-table scan because NULL values cannot be indexed. If you have no choice, but to have this condition in your query, consider replacing it with a NVL function.

Recommendations:

If you have a null in your where clause you may have to keep the following in mind:

x� When you have “IS NOT NULL” type WHERE clause will use an index

x� When you have “IS NULL” type WHERE doesn’t use an index

Concern #6:

I have a query,

ũ������� ������ ſƋƀ� ����� �������� ������������ſ�����ƀ�ʰ�ŧ����Ũ�ũ

I have proper index on name column then why is the query engine not utilizing an index?

Page 5: Db performance optimization with indexing

Healthy Code May 201424

Even though the name column has an index, the upper functions will invalidate the index and WHERE clause predicates might invoke FTS (unnecessary I/O).

Recommendations:

In such cases, use Function-Based index on that column. Function-Based indexes give the ability to index computed columns and use theses indexes in a query as shown here.

������� ������ ����ɏ���� ��� ��������ſ�����ſ�����ƀƀŚ

Concern #7:

I have created a Function-based index on a table column, yet when I check my execution plan, the optimizer ignores the Function-based index?

Typically, function-based indexes or any index are ignored when analyze the index has not been performed.

Recommendations:

After creating a function-based index, don’t forget to re-gather table statistics and get extended statistics on the function.

Concern #8:

I have a query,

ũ������� ����� ����� �������� ������ �������ʫ�ɨ�ʰ�ɬɥɥɥɥɨ����ũ�������Ƌ�������������������� ���������� ŶŶ� ŧ� ŧ� ŶŶ� ��������� ʰ�ŧ����������ŨŪ�

I have a proper index on these columns but no use of the index.

This may happen if you are performing mathematical operations on the indexed column then oracle will invalidate the index and will go for the full table scan.

Concern #9:

I have a following query

ũ�����������������������������������ʰ�����ſś���ɏ����ř�����ƀŪ�

In this case name column is indexed but oracle is not using an index. Why?

When an indexed column appears on both sides of an

operator, the index for that column is disabled.

Recommendations:

You can rewrite the above-mentioned query as

ũ������������������������������������ʰ����ſś���ɏ����ř�ʩƀŪ

Concern #10:

I have following query

������� ����ř� ����������ɏ��� ��������������� ������ ����������ɏ��� ���� ���ſ�����������������ɏ���������������ƀ�

Inspite of having a proper index on these columns why doesn’t oracle use it?

If we use the NOT EXISTS then nested index scans will be used in the sub query for each row in the DEPARTMENT table. The only records that will be returned from DEPARTMENT are those that return no rows from the sub query, and no full table scans are performed by the sub query.

Recommendations:

The following query statement is more efficient.

������� ����ř� ����������ɏ��� ��������������ř������ ���� ������� ſ�����������������ɏ��� ���� ��������� ������department.department_id=employee.

department_id)

Concern #11:

In my query, I have an index on a DATE column but oracle is not using index if I fetch results using JDBC driver?

This might happen due to data type conversion between Date and TimeStamp. Developers, typically use the setTimestamp method in order to set time. When this is done, the index on the DATE column will not be used. This is because, oracle internally converts/casts datatypes (of date to timestamp) .

Recommendations:

You can address this problem with the following:

������������h ��������������ſ�Ŝ�������ſƀƀŚ

����Ŝ���������ſ���ř� ���� ������Ŝ���Ŝ

Page 6: Db performance optimization with indexing

Healthy Code May 2014 25

����ſ�ř�ſ��������ƀ���ɏ���Ŝ�����ſƀƀƀŚ

Concern #12:

In spite of having index on “first_name” and “last_name” columns the query

“�������Ƌ�������������������������ɏ����������ŧ��ʩŨ��������ɏ����������ŧʩŨŪ

takes much longer than expected.

The use of ‘OR’ statements confuses the optimizer (Cost Based Optimizer). It will rarely choose to use an index on column referenced using an OR statement.

Recommendations:

You can work around this issue by using UNION ALL as shown here.

������� Ƌ� ���� ��������� ������ �����ɏ����������ŧ��ʩŨ������������������Ƌ������������������������ɏ����������ŧʩŨŚ

Concern #13:

I have created composite index on the column but how does it work with my query?

A composite index contains more than one key column. Composite indexes can provide additional advantages over single column indexes. Consider

creating a composite index on columns that are frequently used together in WHERE clause conditions combined with AND operators, especially if their combined selectivity is better than the selectivity of either column individually. Even If you do not include the first column of a concatenated index in the WHERE clause of your statement then also Index Skip Scanning will be used.

Summary

This article was just a brief overview at database indexing with some light on b-tree index, bitmap indexes, function-based indexes, and composite indexes. Index efficiency is hard and finding appropriate index even harder. We hope that these tips when used appropriately may help you debug performance issues, even after you have created the index on the relevant columns.

In general, when things are really slow due to a SQL statement, in your application, use the EXPLAIN PLAN to look at the execution plan of the statement. Following this, make the changes in your SQL based on cost estimation.

Remember that “FULL TABLE SCANS ARE NOT ALWAYS BAD” and “SQL INDEX != FASTER ACCESS” in all scenarios.

Happy indexing!!!

Ankit Kumar is currently serving Successfactors (SAP Cloud) as a Principal Engineer. His work is with the Employee Central (EC) product wherein his main focus is to make EC world’s most high-performing, scalable, and blazing fast cloud platform. Prior to this, he worked with Oracle as a technology lead and Hewlett Packard (HP) as a software analyst. He holds a patent and disclosure in database and network technologies, respectively.

NS Sekar

Sekar is Vice President of Engineering at Success

Factors. He has previously worked as Director

at Yahoo and Informatica. He is a seasoned tech-

nology and product development executive with

experience in building and scaling distributed en-

gineering and product teams from multiple ear-

ly-stage startups to the next level. His expertise

includes Data Integration, Data Quality, Web Ana-

lytics, Internet Platforms, and SaaS

Ankit Kumar