Skip to Main Content
  • Questions
  • Which Index is Better Global Or Local in Partitioned Table?

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Aravindhan.

Asked: January 16, 2013 - 12:53 am UTC

Last updated: June 18, 2020 - 2:55 am UTC

Version: 11.1.0

Viewed 50K+ times! This question is

You Asked

We have partitioned table based on date say startdate (Interval partition , For each day)
We will use query that will generate report based on days (like report for previous 5 days)
Also we use queries that will generate report based on hours (like report for previous 5 hours)
So there are queries will access data within partition and across partition as well
So please suggest whether we can for global or local index on startdate

and Tom said...

well, if you are going to cross partitions - hitting 5 days worth of data - hopefully you would NOT be using an index at all. Hopefully you would be using a full scan of the five partitions since you are hitting every row.

If all of your queries include "startdate" in the predicate and you think you'll hit partitions at the most typically - it is likely you want to employ locally partitioned indexes for most all of your indexes.

And startdate doesn't need to be in all of these indexes (they do not need to be prefixed with startdate). Only when you are going after the previous N hours might you want an index that starts with startdate.


for example, suppose you have queries like:

select .... 
  from t
 where startdate between sysdate and sysdate-5
   and x > 100;

select .... 
  from t
 where startdate between sysdate and sysdate-2
   and x > 100;



it MIGHT make sense to have a locally partitioned index on X, just on X. If x > 100 returns a very small number of rows from those five partitions then an index on X and just on X would be appropriate. We will do five index range scans (which is acceptable) to find the rows.

For the second query we would just do two index range scans (again, acceptable).


You would want a globally partitioned index on X if you did queries like:

select .... 
  from t
 where startdate between sysdate and sysdate-50
   and x > 100;

select .... 
  from t
 where x > 100;



assuming again that x > 100 returns a small number of rows from the candidate set of data. We'd want a global index on X in this case because doing 50 index range scans is becoming unacceptable - too much work. And in the second case - we'd do N range scans where N was the number of partitions in the table.



If you just query:

select .... 
  from t
 where startdate between sysdate and sysdate-5;

select .... 
  from t
 where startdate between sysdate and sysdate-2;


I would want no indexes - just full scan the partitions and be done with it, an index is useful to retrieve a SMALL NUMBER of rows from a large set of data, if you are looking at every row in a set of data - indexes are something to be avoided.


If you query up for the last 5 hours of data - again, you probably DON'T want any indexes either. Early in the day - you'd be returning every row from the partition. In the middle of the day, you'd be returning almost 50% of the data. At the end of the day - you'd be returning about 20% of the data. That is too much of the data to be using an index - a nice full scan would be best.


You'd only want an index on startdate if you run a query that returns a small number of rows from a large number of rows (eg: if you asked for a 5 minute window of data - indexing startdate would make sense - otherwise probably not)

Rating

  (10 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

global or local

Laurent Schneider, January 16, 2013 - 3:22 pm UTC

>> where startdate between sysdate and sysdate-50 and x > 100;
>
> We'd want a global index on X in this case because doing
> 50 index range scans is becoming unacceptable - too much
> work

A global index on X? Partitioned by X? Or just a non-partitioned index on X?

I like this question very much. And the answer too :) But it is a difficult question.

Until now I almost accepted the approach "local for datawarehouse and global for oltp"

Happy 2013
Laurent
Tom Kyte
January 17, 2013 - 8:26 am UTC

A global index on X? Partitioned by X? Or just a non-partitioned index on X?


sure, either one - you decide. You use your knowledge of the volume of data, the type of data, the nature of the data to decide.

Would the global index benefit from partitioning? Is it large enough to benefit from it? Would the height of the index partitions be reduced by one or two benefiting queries? Would it be much easier to manage?


Until now I almost accepted the approach "local for datawarehouse and global
for oltp"


far too simplistic. The decision to go local or global isn't driven by the type of system - but rather by how the index will be used!


Typically - you would like to use local indexes when you have rolling windows of data (drop old partition, add new partition) - but we do that in OLTP as much as we do that in data warehousing (that orders table that needs seven years of history online in warehousing might only need one years worth online in OLTP, that audit trail, ....)

but that is why we have the ability to maintain global indexes during the truncate/drop of an old partition - so no need to rebuild. And in a future release - we'll have a third way to deal with global indexes (the first two being a) let them go invalid and rebuild and b) maintain them in real time during the drop/truncate)

and happy 2013 and beyond to you as well!

parallel

Laurent Schneider, January 17, 2013 - 12:23 pm UTC

Thanks for the follow up !

In the example you gave, you mentioned the amount of work to select from 50 local index partition, which would probably acceptable in datawarehouse where you parallelize queries

also mentioned in the doc :
http://docs.oracle.com/cd/E14072_01/server.112/e10837/partition.htm

> If the application is an OLTP one and users need quick
> response times, use a global index. If the application is
> a DSS one and users are more interested in throughput,
> use a local index.

I understand this is simplistic

difference between latch and lock

xiaowei, January 18, 2013 - 8:25 am UTC

difference between latch and lock,can you give me an example.
Tom Kyte
January 18, 2013 - 10:33 am UTC

locks, known as enqueue locks, are designed to be heavyweight things, held for long durations of time (relatively speaking) and are taken out in an orderly fashion. that is - if transaction A has a lock on X and transaction B wants X, transaction B will get in a queue for X. If other transactions desire that same lock - they'll join B in the queue. When A releases the lock, the waiting transactions will get it one after the other - in an orderly fashion.


latches are designed to be very lightweight and held for very very very short periods of time. they are used to serialize access to memory structures typically and the modifications made to these structures do not have to be committed - so the latch is held just long enough to modify/read the structure typically. Access to a latch is not orderly - you do not get in a line like you would for a lock. It is more like a mob of transactions all trying to get the latch - when the latch holder gives up the latch - they just throw it at the mob of waiting transactions and the first one that grabs it - gets it.


Partitioning vs Non partitioning

Pradeep, August 06, 2013 - 4:35 pm UTC

Hi Tom,

In our Database all of the big transaction tables are partitioned , however there are some tables like error tables which are not partitioned. These error tables are used for reporting purposes . Initially these tables were very small but with course of time they have grown considerable in size. Although they are not impacting any system , but yes queries have now become slow.


Since most of the reporting from these tables are done on "date" field,
1. Is it good to make partition in these tables.

As I know partitioning only divides the storage into smaller chunks so
2. Is it going to cost (In terms of storage or anything ) if we partition these error tables, compared to let them as they are now and focus just on tuning queries.

Appreciate your response , Many thanks !!


Tom Kyte
August 08, 2013 - 4:56 pm UTC

1) sounds like it very well could be.

2) they will probably be about the same size - in most cases. However there are examples where that will not be true.

For example, if you delete from these tables - and your partition key is always increasing over time, you won't be able to reuse that deleted space in "old" partitions since you don't insert those lower partition keys anymore.


Locally partitioned indexes VS non-partitioned indexes

Reader, July 22, 2015 - 6:26 pm UTC

Hello Tom,

I am looking for some inputs on local versus global partitioning on indexes. Appreciate your help.Thank you.

Ours is a batch processing application (OLTP), with transaction tables each more than 10 million rows. The transaction tables are currently monthly range partitioned, however the rows in recent partition of last year are going over a million now hence we are planning to convert them to daily.

The transaction tables have indexes which are locally partitioned. Most of our queries which go against these transaction tables have date predicates in them, however there are some instances where a date is not available to be passed in.
In most of the places the date predicates passed is a single date, however there are few places where the date predicates are range hence can go beyond a single day to even 30 days.

My questions: - 1. In such cases what should be the points to consider to decide whether to go for a local partitioned index or a global non partitioned (normal) index.
2. If I have to join 2 (range partitioned) transaction tables on columns that are indexed. (Parent table A joined with child table B and table B has a foreign key for table A. Foreign key indexed in table B).
If the join on these tables on this foreign key fetches less than 10 rows from the child table, then does it make sense to create a locally partitioned index on the foreign key column? Or a normal index (non-partitioned global) ?


Excerpt from Oracle docs I read ( http://docs.oracle.com/cd/E18283_01/server.112/e16541/part_oltp.htm#CEGECIGF ): - “With partitioned indexes, there are always multiple segments. Whenever Oracle Database cannot prune down to a single index segment, the database has to touch multiple segments. This potentially leads to higher I/O requirements (n index segment probes compared with one probe with a nonpartitioned index) and can have an impact (measurable or not) on the run-time performance. This is true for all partitioned indexes.”

I am bit confused and looking for some advice/pointers as in what points to consider while making the decision to use local indexes vs global indexes. Is the no-separate maintenance required while performing DDL’s on partitions (MERGE/SPLIT/DROP) the main reason to go with locally partitioned indexes as against non-partitioned global indexes?

global index

tinku, September 29, 2017 - 6:38 am UTC



Here is the reference from oracle document

""Oracle does not support global nonprefixed partitioned indexes"


I was trying this scenario and I can create nonprefixed partitioned index. Here is the proof


create table test(x number, y number )
partition by range(x)
(partition p1 values less than (100),
partition p2 values less than (200),
partition p3 values less than 300))


create index idx_t on t(y) global;

Is this documentation bug? or my understanding is flawed?

FYI - I have tested this feature in Oracle 11g R2.



Connor McDonald
September 29, 2017 - 1:14 pm UTC

Your index is not partitioned.

""Oracle does not support global nonprefixed partitioned indexes"

global index

tinku, September 29, 2017 - 6:40 am UTC

There is a typo in my previous query. The index should be

create index test_idx on test(y) global;

global index

Tinku, September 29, 2017 - 4:15 pm UTC

Thanks Connor for your response. Does it mean we can created non-partitioned index on the partitioned table ?

what are all the pros and cons is using prefixed global partitioned index vs non-partitioned index on the partitioned table in terms of performance?


Connor McDonald
September 29, 2017 - 9:32 pm UTC

"Does it mean we can created non-partitioned index on the partitioned table?"

Yes.

"what are all the pros and cons is using prefixed global partitioned index vs non-partitioned index "

In my experience, global partitioned indexes are rare except for one special case, where you partition an index to ease contention on index blocks (eg leading sequence number key)

global index

tinku, October 01, 2017 - 8:23 am UTC

Thanks Connor. In which situtation, we might require non-partitioned index on the partitioned table ? I could not think of any differences between both the prefixed global partitioned index vs non-partitioned index on the partitioned table.Please shed some lights on this.

Connor McDonald
October 06, 2017 - 5:41 am UTC

In which situtation, we might require non-partitioned index on the partitioned table

Lets say you have a table with 500 partitions (on a date column) and you also have a customer column that you want to do fast access on.

create index IX on T ( customer) local;

means that whenever you do:

select * from T where customer = 'CONNOR'

means you need to 500 index probes...one for each partition.

Whereas if you do:

create index IX on T ( customer); -- ie, global

then it is a single index probe.

This doesnt mean that *every* index like this should be global. For example, if it turns out that your most common query is:

select * from T where customer = 'CONNOR' and date_col > "1 week"

(assuming here the "date_col" is your partitioning column), then a local index would probably be fine, and you avoid some of the maintenance issues of a global index

Local non prefix index with partition name used with table

A reader, June 17, 2020 - 7:29 pm UTC

Hi Connor,
So, if we consider a table EMP is a list partion based on GENDER :
1. P_MALE
2. P_FEMALE

and if application is designed in such a way that select on EMP table will always contains partion name.
e.g. if we want to find no of active female & male employees using two separate sqls, it is worth creating local non prefixed index on status column and sqls will be like
Select * from emp partition (p_male) where status = 'ACTIVE'
Select * from emp partition (p_female) where status = 'ACTIVE'

Right?
Connor McDonald
June 18, 2020 - 2:55 am UTC

*if* you need the index, the local would definitely be the way to go in this situation.

But it is still *IF*, because

a) status=active might be 90% of the rows .... so index a bad idea

b) status=active might be only 10% of the rows, but scattered everywhere through the table...so index *might* be a bad idea

c) status=active might be 30% of the rows, but all clustered together...so index probably a good idea

etc etc

Similarly, maybe subpartitioning by status is an option.