I'm Working with a new Oracle DB, with one table having the following indexes:
Index 1: ColA, ColB
Index 2: ColA
Is the second index redundant, and Will this have a negative impact on performance?
Google is my best friend :
http://www.orafaq.com/node/926
The main point of this article is :
If 2 indexes ( I1 and I2 ) exist for a table and
the number of columns in Index I1 is less or equal to the number of column in index I2 and
index I1 has the same columns in the same order as leading columns of index I2
Then
If index I1 is UNIQUE then
If index I2 is used to support Foregh Key or for Index Overload then
Do Nothing
Else
Index I2 can be DROPPED
End If
Else
Index I1 can be DROPPED
End If
End If
And I'm agree with that !
In fact, search "duplicate indexes" in Google to have different kind of answer.
The second index is different and is not redundant per se.
How about this query:
SELECT DISTINCT ColA FROM TABLE WHERE ColA IS NOT NULL;
Oracle can answer this question entirely from Index 2. Now, index 2 would be expected to be small (less blocks) than index 1. This means, it is a better index for the above query.
If your application never does a query that suits Index2 better than Index1, then it is redundant for your application.
Indexes are always a performance tradeoff. When an insert, update or delete is performed there is extra work to do in order to maintain each additional index.
Is this more than compensated for by the increased performance provided by the index? Depends on your application and data usage.
The second index is sort of redundant - any operation that uses Index2 could use Index 1. Also, writes will be slightly slower since there is another index to update.
That said, Index2 is not entirely redundant as it could be a bit faster since the index itself is probably going to be significantly smaller.
there is a chance that if your statistics go out of date, the optimizer might choose index 2 when index 1 is needed. (a hint to the optimizer would solve that, of course.)
Related
I am running a query on a large table and I am expecting a large number of returning row.
unfortunately I need to order the result by 2 columns, which makes the query quite slow.
I added an index to those specific columns but was wondering, if the order direction makes a difference.
one column is ordered desc and one is order asc.
thanks and best wishes,
e.
Your query might benefit from an index ordered the same way as your order by clause e.g.
create index index1 on table1 (col1 desc, col2 asc);
Whether it will benefit depends on the relative cost of the index scans and table lookups versus a simple full table scan. If the number of rows you want is low relative to the total number of rows in the table the query might benefit.
The only way to know for sure is try it.
I have a table created which is partitioned by year and I have the below two local non unique indexes created on the table
idx1 : (year, wk, pd, sku)
idx2 : (sku, str )
My undersatnding is that idx2 is redundant and and you could just create
one index with (year,wk, pd, sku, str) to take adavantage of skip scans.
Any thoughts or comments?
Indexing the partition key is redundant as partition pruning will effectively "index" that field, and it pruning occurs before any index reads. At which point, skip scans will act normally, assuming the optimizer doesn't score the skip scan higher than a full partition scan.
Assuming you have a query specifying only sku and str, then idx2 is not redundant.
Using idx1, you've still got at least 52 weeks x ?? (don't know what pd is...) = 52 or more index sub-trees for an INDEX SKIP SCAN to look through, per partition.
An INDEX SKIP SCAN on idx1 will do 52+ index probes. An INDEX RANGE SCAN on idx2 will to one probe per partition (which you could cut down to 1 overall probe by making that a global index).
So, idx2 offers benefits. Whether those benefits justify the cost of a 2nd index on the table depend on your usage patterns (writes vs reads) and performance goals.
I´m currently working on optimzing my database schema in regards of index structures. As I´d like to increase my DDL performance I´m searching for potential drop candidates on my Oracle 12c system. Here´s the scenario in which I don´t know what the consequences for the query performance might be if I drop the index.
Given two indexes on the same table:
- non-unique, single column index IX_A (indexes column A)
- unique, combined index UQ_AB (indexes column A, then B)
Using index monitoring I found that the query optimizer didn´t choose UQ_AB, but only IX_A (probably because it´s smaller and thus faster to read). As UQ_AB contains column A and additionally column B I´d like to drop IX_A. Though I´m not sure if I get any performance penalties if I do so. Does the higher selectivity of the combined unique index have any influence on the execution plans?
It could do, though it's quite likely to be minor (usually). Of course it depends on various things, for example how large the values in column B are.
You can look at various columns in USER_INDEXES to compare the two indexes, such as:
BLEVEL: tells you the "height" of the index tree (well, height is BLEVEL+1)
LEAF_BLOCKS: how many data blocks are occupied by the index values
DISTINCT_KEYS: how "selective" the index is
(You need to have analyzed the table first for these to be accurate). That will give you an idea of how much work Oracle needs to do to find a row using the index.
Of course the only way to really be sure is to benchmark and compare timings or even trace output.
In general, every index on a table slows down INSERTs into the table
by a factor of three; two indexes generally make the insert twice as
slow as one index. (Yet, a two-part single index is not much worse
than a single-part single index).
I got this from the book Oracle 9i Performance Tuning Tips and Techniques by Richard Niemiec (Osborne Oracle Press Series).
What does the following terms mean:
Two-part single index
Single part single index
Are there any more kinds of indexes?
.
By two-part index I presume Rich means a composite index, that is an index built on multiple columns. Like this:
create index t23_t_idx on t23 (col4, col2);
Whereas a single part index indexes a single column:
create index t23_s_idx on t23(col1);
The indexes created above are b-tree indexes. Oracle has many other types of indexes. For starters, indexes can be unique, in which case they only allow one instance of the given value in the indexed column (or permutation of values for composite columns).
There are also bit-mapped indexes, which impose a much higher performance penalty on DML but which speed up certain types of query; it is rare to come across bitmapped indexes outside of data warehouses.
We can create function-based indexes which allow us to index the results of a deterministic function (i.e. one that is guaranteed to produce the same result for a given input). This is how we can build an index on a date column which ignores the time element:
create index t23_fbi_idx on t23( trunc(col_34));
We can also build domain indexes on text columns. And there are special indexes for partitioned tables.
All of these are covered in more detail in the documentation. Find out more.
I would assume that the author is referring to a composite index when he talks about a "two-part single index". The term "composite index" is a far more common way to refer to an index on multiple columns of a table.
If you have a single composite index on two columns, there is only one index structure that needs to be maintained during an insert so the overhead of index maintenance is not much different than the overhead of maintaining one single-column index.
CREATE TABLE t1 (
col1 NUMBER,
col2 NUMBER,
col3 NUMBER
);
CREATE INDEX t1_composite_idx
ON t1( col1, col2 );
On the other hand, if you create separate indexes on each column individually, Oracle has to maintain two separate index structures which does roughly double the amount of index maintenance that is needed
CREATE TABLE t1 (
col1 NUMBER,
col2 NUMBER,
col3 NUMBER
);
CREATE INDEX t1_idx1
ON t1( col1 );
CREATE INDEX t1_idx2
ON t1( col2 );
I would be rather leery, however, of the "factor of three" that the author quotes, however. There are a lot of variables that come into play that are not captured by that particular rule of thumb. It's useful to remember that adding indexes imposes potentially substantial costs on insert operations but it's much more useful to measure the actual cost that you are imposing when you are weighing the trade-offs to creating another index.
Are there any more kinds of indexes?
As for your last question-- Oracle has quite a few different types of indexes (particularly if we are counting composite indexes as a different type of index). This answer has been solely dealing with b*-tree indexes which are what people normally mean when they refer to "indexes" without qualifiers. Oracle, however, supports a number of different types of indexes-- b*-tree indexes, bitmap indexes, Text indexes, etc. It creates LOB indexes. It supports user-defined extensible indexes. And within each type of index, there are often dozens of different options. For example, you can create a function-based b*-tree index or a bitmap join index, you can specify custom lexers for an Oracle Text index, or you can define your own index structure for your own custom type.
Since the author does not seem to actually ever define the term, I can only guess that they mean a two-part single index is a composite key comprised of two columns and a single-part single index is an index based on a single column.
As always, I apologize if this is a stupid question (two questions, actually). I'm not a DBA, so I know very little about indexes. My questions are:
Is there any cutoff point (in terms of number of rows) at which an index would be pointless? For example, is there any benefit to an index on a lookup table with 10-20 rows?
I've read some things about covering indexes in Oracle, and the concept makes sense in that the data can be retrieved directly from the index and a trip to the table is unnecessary. How can I tell if an index is a covering index? Is this a value set when the index is created, or by default based on the rows that the index includes?
I hope this makes sense.
Richard Foote has a series of blog posts on indexes for small tables. The short answer is probably not (but the long answer is much more interesting).
A covering index is a general term for an index that contains all the columns that are part of either the SELECT list or the WHERE clause for a table. It is not a property of an index-- any index can be a covering index for some query. It is something that is specific to a query and to the indexes available to the optimizer.
Small tables can be created as an "indexed oriented table" in which case the table and the index are the same "object" in storage. I believe a primary key is required for an IOT. Before IOTs were available it was in many cases a judgement call. Certainly, if the index was almost as big or bigger than the table it's useless unless it's being used to enforce uniqueness.
another Richard Foote link
You have to look at the query being run and compare it to the index. An index on (A, B) covers:
select B from T where A = 3