Partition Pruning works!

August 23rd, 2005 by Peter Scott

In a recent post, David Aldridge discussed an approach for efficiently rebuilding a table so that partition key migrated from one column to another. This is a somewhat specialised operation and one that most people need not consider (well not unless you do data warehousing and need to revise a partitioning scheme for performance reasons)

In the follow-up postings I discussed with David the use of day level partitions as an alternative to month level partitions especially if you could eliminate the need for sub-partitions. In David’s case the use of LIST sub-partitions is relevant, but in a DW system we recently re-designed we gained query-time advantage by moving away from HASH sub-partitions. David did however ask if we still got partition elimination from month level queries on a day level table. The answer to this is “YES”

In our DW we have a base daily sales table BASE_S_DY (540,400,000 rows) with 9 dimension key columns (including actual_dt) and a variety of measures. Each key column is bitmap indexed and also has a RELY foreign key constraint to the dimension data tables. We also have defined Oracle dimension objects to support MV summaries.

For my simple test I am not using MV query rewrite. I have a simple dimension table DW_CAL_DAY that contains all available dates in our DW.

SQL> desc dw_cal_day
Name Null? Type
—————————————– ——– ————–
ACTUAL_DT NOT NULL DATE
DAY_OF_WEEK NOT NULL VARCHAR2(10)
WEEK_NO NOT NULL NUMBER(6)
MONTH_NO NOT NULL NUMBER(6)
CALENDAR_YEAR_NO NOT NULL NUMBER(4)
CALENDAR_MONTH NOT NULL VARCHAR2(10)
DATESTAMP DATE

 

There is a bitmap indexes on the MONTH_NO column of DW_CAL_DAY.

explain plan for
select sum(SALES_VALUE_AT_SELL_LOC) from BASE_S_DY s, dw_cal_day d
where s.actual_dt = d.actual_dt
and month_no = 200507
and customer_no = 534879262

Gives the following plan: (edited to fit page by removing parallel query columns
PLAN_TABLE_OUTPUT
—————————————————————————

————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop
————————————————————————-
| 0 | SELECT STATEMENT | | 1 | 32 | 1158 (1)| | |
| 1 | SORT AGGREGATE | | 1 | 32 | | | | | | |
| 2 | SORT AGGREGATE | | 1 | 32 | | |
|* 3 | HASH JOIN | | 67 | 2144 | 1158 (1)| |
| 4 | TABLE ACCESS BY INDEX ROWID | DW_CAL_DAY | 30 | 390 | 5 (20)| |
| 5 | BITMAP CONVERSION TO ROWIDS | | | | | | | | | |
|* 6 | BITMAP INDEX SINGLE VALUE | PS_WK_MO | | | | | | | | |
| 7 | PARTITION RANGE ITERATOR | | | | | KEY | KEY | 75,01 | PCWP | |
| 8 | TABLE ACCESS BY LOCAL INDEX ROWID| BASE_S_DY | 1515 | 28785 | 1154 (1)| KEY|KEY
| 9 | BITMAP CONVERSION TO ROWIDS | | | | | |
|* 10 | BITMAP INDEX SINGLE VALUE | SSBASED_CU | | | | KEY | KEY
———————————————————————————–

Predicate Information (identified by operation id):
—————————————————

3 - access(”S”.”ACTUAL_DT”=”D”.”ACTUAL_DT”)
6 - access(”D”.”MONTH_NO”=200507)
10 - access(”S”.”CUSTOMER_NO”=534879262)

And the stats:

Statistics
———————————————————-
54 recursive calls
4 db block gets
252 consistent gets
151 physical reads
1044 redo size
219 bytes sent via SQL*Net to client
277 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
36 sorts (memory)
0 sorts (disk)
1 rows processed

The key point here is that there is a partition range interator at id=7 the key value indicates that the partition key is identified at query time.

For my table S_BASE_DY contains 19,000,000 rows for the month being queried and we only need to access 86 rows to get the total sales for the customer in question. The total time to execute my query is around 2 seconds. I am happy with that!

Comments

  1. Pete_S Says:

    Alberto Dell’Era reminds me (see http://pjs-random.blogspot.com/2005/04/more-about-me.html#c112483484725787165) that whenever we access more than one partition we use global statistics. That’s a point worth remembering.

    (Oh, and by the way we do keep our table and partition stats up to date)

  2. David Aldridge Says:

    Very interesting stuff Pete. Now I wonder why I couldn’t get that to work on our system. What version are you on there?

  3. Pete_S Says:

    And the versions…
    9.2.0.6 on Solaris 64 bit.

    We have parallel query and star transforms enabled. Bitmap indexes on the fact dimensions and on the reference FKs. The plan shows parallel query in use but no STAR transforms (and I would not expect any either)

  4. David Aldridge Says:

    Hmmm … 9.2.0.6 on HP/UX 64bit here, so that’s all consistent.

    How do you feel about temporarily dropping the dimension on the date table to see if that is what is promoting the partition pruning, Pete :D

  5. Pete_S Says:

    Seeing that I like you :D
    I’ll give it a go on our TEST box - maybe this afternoon

  6. Pete_S Says:

    No difference seen before or after dropping the time dimension - still get the elimnation of partitions

    But I didn’t think it would make a difference - dimensions only really affect query rewrite.

  7. David Aldridge Says:

    Hmm, yes that’s what I thought. I’m scratching my head trying to work out why PP isn’t working here under what appear to be similar circumstances — FK constraints, PK constraints, not null constraints etc..

    More thinking time needed. It sounds like one of those problems where the answer pops into your head in the middle of the night.

  8. David Aldridge Says:

    Pete,

    I started with another response to this, having found more information on the subject, and it got so involved that it turned into a blog entry.

    http://oraclesponge.blogspot.com/2005/08/partition-pruning-and-dimension-tables.html

  9. Pete_S Says:

    A nice posting, David