What is the relationship between "Composite indexing" and "Index Skip Scan"?
If you create a composite indexing on 3 columns eid, ename, esal?
If I mention only
eid=10after where clause will the indexing be called ?select * from emp where eid=10;If I mention only eid=10 and ename='Raj' will the indexing be called ?
select * from emp where eid=10 and ename='Raj';If I mention in different order like esal=1000 and eid=10 will the indexing be called ?
select * from emp where esal=1000 and eid=10;If I mention in reverse order like esal = 1000 and ename = 'Raj' and eid = 10 will the indexing be called ?
select * from emp where esal=1000 and enam='Raj' and eid=10;
Need a solution for this with detail table representation with data how it does?
In all four cases you presented, Oracle would do a normal index seek (binary tree search) on the leading column
eidbecause an equality predicate was provided for this column in each of your cases. But what else it does with the index depends on what other columns you're filtering on:First column (
eid) only: after finding the firsteid=10entry in the leaf blocks using a binary search/seek, Oracle will scan that and any subsequent leaf blocks it needs to, moving through each block (single block reads) using a linked list, until it finds the firsteidvalue that is not 10. As it does so it gathersROWIDs containing the table segment physical row address which it issues single block reads byROWIDto obtain the rest of the row.First two columns (
eidandename): becauseenameis the second column in the index, Oracle will use botheidandenametogether at the same time as it performs the binary search (seek) to find the first leaf block entry whereeid=10andename='raj'. It will then procede as above scanning leaf blocks until it finds the first row for which either of these columns have different values.First and third column (
eidandesal): becauseesalis the third column and you're skipping the second column, Oracle cannot use a single binary search/seek operation onesal. It has two choices:3a. It does a binary search/seek only on the leading column,
eid, but once it finds the firsteid=10value in the leaf blocks it will do a normal scan of leaf blocks following that linked list - looking through alleid=10rows, but grabbingROWIDs only for those withesal=1000.3b. Or, it does a skip scan: for every distinct value of the missing intermediate column(s) (
ename) within the scope defined by any leading columns (eid=10rows), it will do a separate binary search/seek on the combinedeid=10 / esal=1000value. This is a seek not a scan, but it is potentially many seeks. If there are manyenamevalues foreid=10this results in a lot of unnecessary single block I/O and can perform poorly. But if there are only a few values, it works pretty well.All columns: Your last example would do a single binary search/seek on all three columns. Nothing special here.
You didn't offer this as an example, but to complete the study:
Third column only: If you queried on
esal=1000only, Oracle could do one of the following:5a. Forget the index and scan the table itself (if 1000 is common)
5b. Do a full scan (scattered read) of 100% of the leaf blocks of the index (if 1000 is uncommon but there are many
eid/enamevalues). This is generally not a great option because in most systems parallel query usign direct path read to read the table itself is much more efficient than a serial scattered read of the index segment.5c. Do a skip-scan, which means a binary search/seek for
esal=1000for every single distinct combination of the preceding,unfiltered columns (eidandename). That would be a lot of seeks, so is rather unlikely the optimizer would choose it unless it believes there aren't very manyeid/enamevalues.Whenever Oracle has a choice, it all depends on statistics and expected cardinalities from each operation which is largely driven by the min/max and # distinct values known for each column combined with overall table row counts. Of course you can force it with hints to if you think you know better than the statistics, but it is recommended to hold off on hinting until one has a solid grasp of how Oracle queries work internally, as you can easily tell it to do the wrong thing.
In conclusion, index column order matters a great deal. It doesn't have to be perfect, as you don't want dozens of indexes on a table, so you have to compromise a little, but carefully considering column order within composite indexes is an important modeling consideration based on the kinds of queries expected or present.