Quantcast
Channel: Mohamed Houri’s Oracle Notes
Viewing all articles
Browse latest Browse all 224

Interval Partitioning and PSTOP in execution plan

$
0
0

The last release of the Northern California Oracle Users Group Journal published a Tom Kyte article entitled Advice for an Oracle Beginner?  In which the author wrote the following phrase “Participation in the Oracle community is what took me from being just another programmer to being ‘AskTom’. Without the act of participating, I do not think I would be where I am today.”

That is 100% correct. I am trying to participate in several Oracle forums including OTN, French Oracle forum and Oracle-list. If I can’t bring my help I try to understand the Original Poster (OP) question and analyze answers brought by other participants. Proceeding as such, I learnt many things. Among them what I learnt today via this otn thread.

For convenience (because it will be very easy for me to find it when needed) I decided to summarize what I learnt to day here via this very brief article. Observe carefully the following execution plan and spot particularly the PSTOP information (1048575)at line 1 and 2

-------------------------------------------------------------------------------------------
| Id  | Operation                | Name                   | Rows  | Bytes | Pstart| Pstop |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |                        |       |       |       |       |
|   1 |  PARTITION RANGE ITERATOR|                        |     2 |    70 |   KEY |1048575|
|*  2 |   TABLE ACCESS FULL      | PARTITION_INTERVAL_TAB |     2 |    70 |   KEY |1048575|
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("TRADE_DATE">=TRUNC(SYSDATE@!))

Does this particular table contain 1,048,575 partitions? Of course it doesn’t.

The name of the table already gives a hint of what is happening here. The table is range partitioned and it is also using interval partitioning feature.  I will expose the second condition that causes the apparition of this magic number in a moment. Here below the model

SQL> CREATE TABLE partition_interval_tab (
  n1 NUMBER
 ,trade_date DATE
 ,n2 number
 )
 PARTITION BY RANGE (trade_date)
 INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
 (
 PARTITION p_1 values LESS THAN (TO_DATE(' 2013-11-11 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
 ,PARTITION p_2 values LESS THAN (TO_DATE(' 2013-12-11 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
 );

SQL> insert into partition_interval_tab values (1, trunc(sysdate), 100);
SQL> insert into partition_interval_tab values (2, trunc(sysdate + 20), 200);
SQL> commit;
SQL> select * from partition_interval_tab where trade_date = trunc(sysdate);

N1 TRADE_DATE                N2
---------- ----------------- ----------
1 20131108 00:00:00        100

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation              | Name                   | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |                        |       |       |    15 (100)|          |       |       |
|   1 |  PARTITION RANGE SINGLE|                        |     1 |    35 |    15   (0)| 00:00:01 |   KEY |   KEY |
|*  2 |   TABLE ACCESS FULL    | PARTITION_INTERVAL_TAB |     1 |    35 |    15   (0)| 00:00:01 |   KEY |   KEY |
-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("TRADE_DATE"=TRUNC(SYSDATE@!))

Nothing special to point out here when the predicate on the partition key represent an equality. But spot what happens when I change the predicate part to be an inequality (>=)

SQL> select * from partition_interval_tab where trade_date >= trunc(sysdate);

N1 TRADE_DATE                N2
---------- ----------------- ----------
1 20131108 00:00:00        100
2 20131128 00:00:00        200

-------------------------------------------------------------------------------------------
| Id  | Operation                | Name                   | Rows  | Bytes | Pstart| Pstop |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |                        |       |       |       |       |
|   1 |  PARTITION RANGE ITERATOR|                        |     2 |    70 |   KEY |1048575|
|*  2 |   TABLE ACCESS FULL      | PARTITION_INTERVAL_TAB |     2 |    70 |   KEY |1048575|
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("TRADE_DATE">=TRUNC(SYSDATE@!))

And here you are; the magic number 1048575 appears which seems to represent the upper band of

Thanks again for Jonathan Lewis who showed this information in the above mentioned otn thread.

I also include few references I have found when searching the number 1048575 on the internet

https://forums.oracle.com/thread/2230426?start=15&tstart=0

http://docs.oracle.com/cd/B28359_01/server.111/b32024/part_avail.htm

And this number seems also to be used by Oracle when auto tuning the db_file_multiblock_read_count parameter value



Viewing all articles
Browse latest Browse all 224

Trending Articles