Partition Elimination

We are having very large database for one particular region of 140+ tables.From which 30+ tables having millions of rows.We are generating reports based on that database.for performance gain,we have added so many Indexes.
Now,we are having more than 30 regions data.So,we have partitioned large tables on region & subpartition on current & history data.
Now,we are trying to do partition elimination.but,it access indexes against partition elimination.All indexes are global index.Index are not partitioned.
Can anybody give inputs on how partition elimination can be achieved?

Thank you very much for reply.
Oracle Version : 9.0.2
partition by Range-List
We are using Bind Variables.
20 percentage rows of tables selected.
30 percentage of specific partition selected.
query & it's explain plan is below:
select coll.* from temp_collstock coll,
acbs_t_calendar cal
where cal.as_of_date_stamp between valid_from_stamp and valid_to_stamp
and cal.portfolio_id in ('DM')
and cal.as_of_date_desc = 'Most recent day'
and coll.portfolio_id = cal.portfolio_id
and coll.most_recent >= cal.most_recent
temp_collstock is partitioned on portfolio_id & subpartitioned on most_recent(having 0 & 1 value.can be treated as flag)
for cal.portfolio_id ,cal.as_of_date_desc values passed at run time.
through calendar table only we can give reference of portfolio_id as well as most_recent.
valid_from_stamp and valid_to_stamp is period for which we have valid data.we pass stamp from calendar table for passed date & portfolio.
index defined on temp_collstock for (valid_from_stamp,valid_to_stamp)
stats gather for all(global,partition,subpartitions,index).
| Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop| |
| 0 | SELECT STATEMENT | | 293 | 45415 | 178 | | |
|* 1 | TABLE ACCESS BY GLOBAL INDEX ROWID| TEMP_COLLSTOCK | 147 | 19404 | 88 | ROWID | ROW L |
| 2 | NESTED LOOPS | | 293 | 45415 | 178 | | |
| 3 | TABLE ACCESS BY INDEX ROWID | ACBS_T_CALENDAR | 2 | 46 | 2 | | |
|* 4 | INDEX RANGE SCAN | ACBS_T_CALENDAR_01 | 2 | | 1 | | |
|* 5 | INDEX RANGE SCAN | TEMP_LOAN_P1 | 2805 | | 61 | | |
Predicate Information (identified by operation id):
1 - filter("COLL"."PORTFOLIO_ID"="CAL"."PORTFOLIO_ID" AND "COLL"."MOST_RECENT">="CAL"."MOST_RECENT"
AND "COLL"."PORTFOLIO_ID"='DM')
4 - access("CAL"."PORTFOLIO_ID"='DM' AND "CAL"."AS_OF_DATE_DESC"='Most recent day')
5 - access("CAL"."AS_OF_DATE_STAMP"<="COLL"."VALID_TO_STAMP" AND
"CAL"."AS_OF_DATE_STAMP">="COLL"."VALID_FROM_STAMP")
filter("CAL"."AS_OF_DATE_STAMP">="COLL"."VALID_FROM_STAMP" AND
"CAL"."AS_OF_DATE_STAMP"<="COLL"."VALID_TO_STAMP")
let us have your inputs.

Similar Messages

  • Partition elimination using views

    Hi all,
    i am having problem with a view which is accessing all the partitions in my table.
    i have a table which has 30 columns and is partition by one column called cid. it is a list partition.
    when i do a query on the table, the explain plan show partition (single)
    ex. select * from table1 where dt=trunc(sysdate) and cid=1 and txt='123A'so the above query works fine and access one partition (value 1(
    now, i created a view base on the table. it looks like this:
    create or replace view view1 as
      column names
    select * from
          (select * from table1 where type='tek') a,
            (select * from table1 where type='pak') b
    where a.userid = b.userid(+)when i issue the statement below, the explain plan show partition (all)
    select * from view1 where dt=trunc(sysdate) and cid=1 and txt='123A'i cannnot seem to find a way for partition elimination using the view. can someone help how to resolve this problem?
    thanks

    consider the following data
    user id       cid       type    name
    ======================
    ABC           1        tek      robert
    ABC           1        pak      will
    TYY          1        tek       smith
    TYY          1        tek       john
    WWW       2        pak      mil
    EEE           2        tek      Josso for example, query a is taking rows with tek value, query b is displaying rows with pak value and both query are join on user id.
    abc row in quey a will join with abc row in query b and this will become one row instead of two.
    so when run query the view such as select * from view1 where cid=1 then i want the view to access partition cid=1 and get the ABC and TYY rows only.
    but it looks it is accessing all partitions which is not what i am looking for.
    let me know if this helps

  • Partition elimination inconsistent behavior

    Hello.
    When we query a partitioned table and partition-aligned indexes are employed, seeks are performed in two steps: If the partition column is used as a predicate, the index is used to eliminate partitions assigned to ranges the predicate values don't fall in.
    Then it proceeds to perform serial scans/seeks in any remaining partitions.
    Now suppose I have a table partitioned on a varchar(10) column. Ranges are defined for values '230' and '281'. In SQL Server 2012 SP1,
    partition elimination won't happen unless i explicitly convert the predicate value to varchar(10).
    NOTE: I'd like to refrain from posting the scripts to generate the entire data structure because they are sensitive.
    Basically the original objects are like the ones below:
    CREATE TABLE TEST
    (PARTITION_COLUMN VARCHAR(10),
    SOME_ID INT)
    GO
    CREATE CLUSTERED INDEX IDX_TEST (PARTITION_COLUMN, SOME_ID) ON PARTITION_SCHEME(PARTITION_COLUMN)
    GO
    CREATE VIEW VW_TEST AS
    SELECT SOME_ID, PARTITION_COLUMN
    FROM TEST
    WHERE SOME_ID = 9
    GO
    Partition scheme has 3 filegroups to cover the ranges '230' and '281' in the partition function. The partition function expects a varchar parameter.
    CREATE PARTITION FUNCTION [RANGE_PROJETOS](varchar(10)) AS RANGE LEFT FOR VALUES (N'230', N'281')
    GO
    When I use a literal varchar value:
    SELECT COUNT(*) FROM VW_TEST
    WHERE PARTITION_COLUMN = '234'
    Seek Keys[1] tell us there is no partition elimination, since its filter implies the selection of all partitions. If I later run this query, the "Actual partition count" value will be 3.
    If I either use a variable or explicitly convert the literal value to varchar(10), partition elimination will be done:
    However, the plan behavior is still inconsistent. The "RangePartitionNew" function is used when the literal value isn't known at compile time, which is acceptable for the query to the left, in the image above, because a variable is being used,
    but not for the query to the right. What makes the latter all the more strange is the fact that it does an implicit conversion to varchar(10) even though it is already explicitly converted to the very same data type!!

    This problem occurs even when querying the table directly instead of the view.
    SELECT * FROM TB_RESULTADO
    WHERE ID_PROJETO_EXTERNO = '234'
    SELECT * FROM TB_RESULTADO
    WHERE ID_PROJETO_EXTERNO = CONVERT(VARCHAR(10), '234')
    Can you verify?  I see the expected actual partition count of 1 with the repro below under SQL 2012 SP2.  To add on to Paul' blog, simply following best practices as to parameterize queries with matching data types will avoid the issue with
    auto parmeterization.
    CREATE PARTITION FUNCTION [PARTITION_FUNCTION](varchar(10))
    AS RANGE LEFT FOR VALUES (N'230', N'281');
    CREATE PARTITION SCHEME PARTITION_SCHEME
    AS PARTITION PARTITION_FUNCTION ALL TO ([PRIMARY])
    CREATE TABLE TEST(
    PARTITION_COLUMN VARCHAR(10),
    SOME_ID INT);
    GO
    CREATE CLUSTERED INDEX IDX_TEST ON TEST(PARTITION_COLUMN, SOME_ID) ON PARTITION_SCHEME(PARTITION_COLUMN)
    GO
    CREATE VIEW VW_TEST AS
    SELECT SOME_ID, PARTITION_COLUMN
    FROM dbo.TEST
    WHERE SOME_ID = 9
    GO
    SET STATISTICS IO ON
    SELECT COUNT(*) FROM VW_TEST
    WHERE PARTITION_COLUMN = CAST('234' AS varchar(10));
    GO
    Dan Guzman, SQL Server MVP, http://www.dbdelta.com
    Dan,
    You have to leave the literal value predicate as it is (without any conversions) to reproduce the aforementioned situation.

  • Partition Tables - issue

    I have lots of partitioned tables in my schema , the requirement is to identify the current partition of the table.
    Let me explain this with an eg.
    Lets say I have a table T , with 24 partitions .. starting for Jan -04 to Dec-05. Now , my current partition is Dec-04. Partition w.r.t sysdate
    How can I achive this by querying the data dictionary

    120196, I think you are mistaken. There is no such thing as "current" partition. Oracle offers 3 types of partition, i.e. range partitioning, hash partitioning and composite partitioning. For all 3 types of partitions, you specify the column you want to partition on. Then, then when you insert/update/delete rows, Oracle does "partition elimination" (if the columns you partitioned is part of the query), which greatly improves performance. So, the partition you deal with (I guess this is what you mean by current partition) is the same one your row has to deal with. Hope this makes it clearer and gives you a 10,000 foot view. There is lots more to partitioning.
    -Raj Suchak
    [email protected]

  • (V7.3) PARTITION VIEWS IN ORACLE7 RELEASE 7.3

    제품 : ORACLE SERVER
    작성날짜 : 2002-05-17
    PURPOSE
    Introduction
    Partition views are a new feature in Release 7.3 design to provide
    better support for very large tables that are commonly found in data
    warehousing environments.
    The partition view feature offers two primary benefits:
    - improved managability and availability of large tables
    - improved performance for table scans on certain queries of
    these large tables
    Explanation & Example
    What is a partion view?
    An example partition view is:
    create view sales as
    select * from jan_sales
    union all
    select * from feb_sales
    union all
    select * from dec_sales
    Each of the base tables (the monthly sales tables) must be identical
    in terms of column names, column datatypes, and indexes. These tables
    must also have a CHECK constraint on its partitioning column (thus,
    the jan_sales table must have a check constraint on the date column
    which constrains the date to fall between Jan 1 and Jan 31).
    All of these base tables, indexes, constraints as well as the
    UNION-ALL view definition are be created by the DBA.
    Managability and availability benefits
    A partition view greatly simplifies the administration of very large
    tables.
    Consider the example of of a data warehousing containing a large
    'sales' table. Once per month, the DBA loads all of new sales data
    into this table. Thus, the DBA would need to drop all of the indexes
    on the sales, load the new data, and rebuild the indexes. Since the
    sales table is very large, this could be a lengthy operation.
    Morever, the sales table is (for most practical DSS application) is
    not available while these load and index operations are occuring.
    Using the partition view feature, the DBA could load the new month's
    data into a separate partition and build indexes on this new partition
    without impacting the original partition view. Then, after the new
    partition is entirely built and indexed, the DBA could recreate the
    UNION-ALL view to include the new partition. The sales partition view
    is unavailable for a very short length of time ... only while the
    UNION-ALL view is being built. Moreover, because the indexes are much
    smaller, the length of time to load and index a new month's worth of
    data is dramatically decreased.
    Performance benefits of partition views
    Any UNION-ALL view (even in earlier releases of Oracle7) can reap the
    aforementioned managability benefits; however, unless the UNION-ALL
    view offers reasonable query performance, the managability benefits
    are useless.
    The enhancement in Release 7.3 is to insure that the query performance
    on UNION-ALL views will at least equivalent to (and, in many cases,
    much better than) single-table access. Note that these performance
    enhancements are only effective when all of the partitions have the
    appropriate CHECK constraints and when all of the partitions have
    identical column definitions and indexes.
    There are two basic performance enhancements for partition views:
    partition elimination
    parallel execution of UNION-ALL views
    Certain queries may not require data from all of the partitions of a
    view partition. For example, consider the following query:
    select sum(revenues) from sales
    where sales_date between '15-JAN-96' and '15-FEB-96';
    With 7.3's new support for partition views, Oracle will evaluate the
    above query using only the January partition and the February
    partition; the remaining ten partitions will not be accessed. This
    feature is commonly called 'partition elimination'.
    Partition elimination is only effective when querying based on the
    partitioning column; in this example, the partitioning column is the
    sales_date column. But the performance savings can be significant. In
    the previous example, the partition view feature results in ten of the
    twelve partitions being eliminated from query processing. This could
    represent six-fold performance gain.
    An additional enhancement in 7.3 is the parallel execution of
    UNION-ALL views. All queries on UNION-ALL views can be executed in
    parallel (when using the Parallel Query Option). It is very
    important to note that the partitioning scheme is absolutely
    independent of the degree of parallelism (this starkly contrasts with
    many of our competitior's parallel query architecture, in which the
    physical data partitioning determines the degree of parallelism).
    Oracle will dynamically distribute the data of a UNION ALL view across
    all parallel query processes, and partition elimintation will not
    impact the degree of parallelism.
    Limitations of Partition Views
    Partition views do not support DML operations. For this reason,
    partition views are most appropriate for read-only applications (such
    as data warehouses).
    Conclusion
    Partition views can be very effective for handling very large tables
    in data warehousing environments. The managability of these large
    tables is vastly improved, with significant performance improvements
    for many queries.
    Reference Ducumment
    ---------------------

    The installer might not be year 2000 compliant. Download a newer version or set your system date back into 1999 ;-)

  • Partition Pruning Aint Happening

    I have a situation where Oracle pruning is not happening and this situation is getting worse when the search criteria is close to current date.
    Table has a date based partition. SQL Statement has 2 partitioned tables. Date range is applied on a relatively smaller daily partitioned table and further joined to the next table (Its also date based partition). First table has partition column in the where clause and it joins to the next table using the partitioned column.
    SQL does partition pruning even for a month range search if the date range is in August. It will do partition pruning only for 25 days for september where clause. Likewise the where clause date range ability for partition pruning goes down and It will only do partition pruning for where clause with 5 days. If the where clause has more than 6 days (Mar 01 Thru Mar 06) in March 2009, Oracle does All partitions.
    Query is examined and it contains partition column in the where clause and we have also gathered 100% statistics of the table which is not partition pruning. Data growth is happening relatively each month.
    Sample: -
    Select 1
    From TAB1, TAB2
    Where TAB1.SELECT_DATE >= '01JAN2009
    And TAB1.SELECT_DATE <= '31JAN2009
    And TAB2.DATE_SELECT = TAB1.DATE_SELECT
    TAB1 Is a daily partition with SELECT_DATE column. Oracle is able to successfully do partition pruning on this table. But TAB2 partition pruning is not happening.
    How I can overcome this situation? Thanks for your help.
    Here is the explain plan for the SQL statement

    | Id  | Operation                            | Name         | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT                     |              |  1224 | 96696 |       |   978K  (4)| 01:21:35 |       |       |
    |   1 |  HASH GROUP BY                       |              |  1224 | 96696 |       |   978K  (4)| 01:21:35 |       |       |
    |*  2 |   HASH JOIN                          |              |  1122K|    84M|    49M|   978K  (4)| 01:21:34 |       |       |
    |*  3 |    HASH JOIN                         |              |  1122K|    36M|       |  5218   (4)| 00:00:27 |       |       |
    |   4 |     COLLECTION ITERATOR PICKLER FETCH| TABLE FUNC   |       |       |       |            |          |       |       |
    |   5 |     PARTITION RANGE ITERATOR         |              |   729K|    22M|       |  5145   (3)| 00:00:26 |   413 |   422 |
    |   6 |      PARTITION LIST ALL              |              |   729K|    22M|       |  5145   (3)| 00:00:26 |     1 |     2 |
    |*  7 |       MAT_VIEW ACCESS FULL           | TAB_01       |   729K|    22M|       |  5145   (3)| 00:00:26 |   825 |   844 |
    |   8 |    PARTITION RANGE ALL               |              |    84M|  3623M|       |   575K  (5)| 00:47:59 |     1 |   970 |
    |   9 |     TABLE ACCESS FULL                | TAB_02       |    84M|  3623M|       |   575K  (5)| 00:47:59 |     1 |   970 |
    Predicate Information (identified by operation id):
       2 - access("TAB_02"."SELECT_DATE"="TAB_01"."SELECT_DATE" AND "TAB_02"."SELECT_NUMBER"="TAB_01"."SELECT_NUMBER")
       3 - access("TAB_01"."TAG_ID"=SYS_OP_ATG(VALUE(KOKBF$),16,17,2))
       7 - filter("TAB_01"."SELECT_DATE"<=TO_DATE('2009-02-10 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))Following is the explain paln where partition elimination happening for a shorter date range search
    | Id  | Operation                            | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT                     |              |   714 | 56406 |   851K  (1)| 01:10:56 |       |       |
    |   1 |  HASH GROUP BY                       |              |   714 | 56406 |   851K  (1)| 01:10:56 |       |       |
    |   2 |   NESTED LOOPS                       |              |   621K|    46M|   850K  (1)| 01:10:55 |       |       |
    |*  3 |    HASH JOIN                         |              |   621K|    20M|  3210   (3)| 00:00:17 |       |       |
    |   4 |     COLLECTION ITERATOR PICKLER FETCH| TABLE FUNC   |       |       |            |          |       |       |
    |   5 |     PARTITION RANGE ITERATOR         |              |   403K|    12M|  3152   (3)| 00:00:16 |   413 |   418 |
    |   6 |      PARTITION LIST ALL              |              |   403K|    12M|  3152   (3)| 00:00:16 |     1 |     2 |
    |*  7 |       MAT_VIEW ACCESS FULL           | TAB_01       |   403K|    12M|  3152   (3)| 00:00:16 |   825 |   836 |
    |   8 |    PARTITION RANGE ITERATOR          |              |     1 |    45 |     2   (0)| 00:00:01 |   KEY |   KEY |
    |   9 |     TABLE ACCESS BY LOCAL INDEX ROWID| TAB_02       |     1 |    45 |     2   (0)| 00:00:01 |   KEY |   KEY |
    |* 10 |      INDEX RANGE SCAN                | TAB_02_PK    |     1 |       |     1   (0)| 00:00:01 |   KEY |   KEY |
    Predicate Information (identified by operation id):
       3 - access("TAB_01"."TAG_ID"=SYS_OP_ATG(VALUE(KOKBF$),16,17,2))
       7 - filter("TAB_01"."SELECT_DATE"<=TO_DATE('2009-02-06 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
      10 - access("TAB_02"."SELECT_DATE"="TAB_01"."SELECT_DATE" AND "TAB_02"."SELECT_NUMBER"="TAB_01"."SELECT_NUMBER")Query where partition elimination not happening on the second table is having date range of 7 days or more. SO the first explain plan is for Feb-01 Thru Feb 10 search
    Query where partition elimination happening on the second table is having date range of 7 days or less. The second explain plan is for Feb-01 Thru Feb-06 search
    This is great.
    Edited by: user10929035 on Mar 24, 2009 8:18 AM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Partition pruning not working for partitioned table joins

    Hi,
    We are joining  4 partitioned tables on partition column & other key columns. And we are filtering the driving table on partition key. But explain plan is showing that all tables except the driving table are not partition pruning and scanning all partitions.Is there any limitation that filter condition cannot be dynamic?
    Thanks a lot in advance.
    Here are the details...
    SELECT a.pay_prd_id,
                  a.a_id,
                  a.a_evnt_no
      FROM b,
                c,
                a,
                d
    WHERE  (    a.pay_prd_id = b.pay_prd_id ---partition range all
                AND a.a_evnt_no  = b.b_evnt_no
                AND a.a_id       = b.b_id
       AND (    a.pay_prd_id = c.pay_prd_id---partition range all
            AND a.a_evnt_no  = c.c_evnt_no
            AND a.a_id       = c.c_id
       AND (    a.pay_prd_id = d.pay_prd_id---partition range all
            AND a.a_evnt_no  = d.d_evnt_no
            AND a.a_id       = d.d_id
       AND (a.pay_prd_id =  ---partition range single
               CASE '201202'
                  WHEN 'YYYYMM'
                     THEN (SELECT min(pay_prd_id)
                                      FROM pay_prd
                                     WHERE pay_prd_stat_cd = 2)
                  ELSE TO_NUMBER ('201202', '999999')
               END
    DDLs.
    create table pay_prd
    pay_prd_id number(6),
    pay_prd_stat_cd integer,
    pay_prd_stat_desc varchar2(20),
    a_last_upd_dt DATE
    insert into pay_prd
    select 201202,2,'OPEN',sysdate from dual
    union all
    select 201201,1,'CLOSE',sysdate from dual
    union all
    select 201112,1,'CLOSE',sysdate from dual
    union all
    select 201111,1,'CLOSE',sysdate from dual
    union all
    select 201110,1,'CLOSE',sysdate from dual
    union all
    select 201109,1,'CLOSE',sysdate from dual
    CREATE TABLE A
    (PAY_PRD_ID    NUMBER(6) NOT NULL,
    A_ID        NUMBER(9) NOT NULL,
    A_EVNT_NO    NUMBER(3) NOT NULL,
    A_DAYS        NUMBER(3),
    A_LAST_UPD_DT    DATE
    PARTITION BY RANGE (PAY_PRD_ID)
    INTERVAL( 1)
      PARTITION A_0001 VALUES LESS THAN (201504)
    ENABLE ROW MOVEMENT;
    ALTER TABLE A ADD CONSTRAINT A_PK PRIMARY KEY (PAY_PRD_ID,A_ID,A_EVNT_NO) USING INDEX LOCAL;
    insert into a
    select 201202,1111,1,65,sysdate from dual
    union all
    select 201202,1111,2,75,sysdate from dual
    union all
    select 201202,1111,3,85,sysdate from dual
    union all
    select 201202,1111,4,95,sysdate from dual
    CREATE TABLE B
    (PAY_PRD_ID    NUMBER(6) NOT NULL,
    B_ID        NUMBER(9) NOT NULL,
    B_EVNT_NO    NUMBER(3) NOT NULL,
    B_DAYS        NUMBER(3),
    B_LAST_UPD_DT    DATE
    PARTITION BY RANGE (PAY_PRD_ID)
    INTERVAL( 1)
      PARTITION B_0001 VALUES LESS THAN (201504)
    ENABLE ROW MOVEMENT;
    ALTER TABLE B ADD CONSTRAINT B_PK PRIMARY KEY (PAY_PRD_ID,B_ID,B_EVNT_NO) USING INDEX LOCAL;
    insert into b
    select 201202,1111,1,15,sysdate from dual
    union all
    select 201202,1111,2,25,sysdate from dual
    union all
    select 201202,1111,3,35,sysdate from dual
    union all
    select 201202,1111,4,45,sysdate from dual
    CREATE TABLE C
    (PAY_PRD_ID    NUMBER(6) NOT NULL,
    C_ID        NUMBER(9) NOT NULL,
    C_EVNT_NO    NUMBER(3) NOT NULL,
    C_DAYS        NUMBER(3),
    C_LAST_UPD_DT    DATE
    PARTITION BY RANGE (PAY_PRD_ID)
    INTERVAL( 1)
      PARTITION C_0001 VALUES LESS THAN (201504)
    ENABLE ROW MOVEMENT;
    ALTER TABLE C ADD CONSTRAINT C_PK PRIMARY KEY (PAY_PRD_ID,C_ID,C_EVNT_NO) USING INDEX LOCAL;
    insert into c
    select 201202,1111,1,33,sysdate from dual
    union all
    select 201202,1111,2,44,sysdate from dual
    union all
    select 201202,1111,3,55,sysdate from dual
    union all
    select 201202,1111,4,66,sysdate from dual
    CREATE TABLE D
    (PAY_PRD_ID    NUMBER(6) NOT NULL,
    D_ID        NUMBER(9) NOT NULL,
    D_EVNT_NO    NUMBER(3) NOT NULL,
    D_DAYS        NUMBER(3),
    D_LAST_UPD_DT    DATE
    PARTITION BY RANGE (PAY_PRD_ID)
    INTERVAL( 1)
      PARTITION D_0001 VALUES LESS THAN (201504)
    ENABLE ROW MOVEMENT;
    ALTER TABLE D ADD CONSTRAINT D_PK PRIMARY KEY (PAY_PRD_ID,D_ID,D_EVNT_NO) USING INDEX LOCAL;
    insert into c
    select 201202,1111,1,33,sysdate from dual
    union all
    select 201202,1111,2,44,sysdate from dual
    union all
    select 201202,1111,3,55,sysdate from dual
    union all
    select 201202,1111,4,66,sysdate from dual

    Below query generated from Business Objects and submitted to Database (the case statement is generated by BO). Cant we use Case/Subquery/Decode etc for the partitioned column? We are assuming that  the case causing the issue to not to dynamic partition elimination on the other joined partitioned tables (TAB_B_RPT, TAB_C_RPT).
    SELECT TAB_D_RPT.acvy_amt,
           TAB_A_RPT.itnt_typ_desc,
           TAB_A_RPT.ls_typ_desc,
           TAB_A_RPT.evnt_no,
           TAB_C_RPT.pay_prd_id,
           TAB_B_RPT.id,
           TAB_A_RPT.to_mdfy,
           TAB_A_RPT.stat_desc
      FROM TAB_D_RPT,
           TAB_C_RPT fee_rpt,
           TAB_C_RPT,
           TAB_A_RPT,
           TAB_B_RPT
    WHERE (TAB_B_RPT.id = TAB_A_RPT.id)
       AND (    TAB_A_RPT.pay_prd_id = TAB_D_RPT.pay_prd_id -- expecting Partition Range Single, but doing Partition Range ALL
            AND TAB_A_RPT.evnt_no    = TAB_D_RPT.evnt_no
            AND TAB_A_RPT.id         = TAB_D_RPT.id
       AND (    TAB_A_RPT.pay_prd_id = TAB_C_RPT.pay_prd_id -- expecting Partition Range Single, but doing Partition Range ALL
            AND TAB_A_RPT.evnt_no    = TAB_C_RPT.evnt_no
            AND TAB_A_RPT.id         = TAB_C_RPT.id
       AND (    TAB_A_RPT.pay_prd_id = fee_rpt.pay_prd_id -- expecting Partition Range Single
            AND TAB_A_RPT.evnt_no    = fee_rpt.evnt_no
            AND TAB_A_RPT.id         = fee_rpt.id
       AND (TAB_A_RPT.rwnd_ind = 'N')
       AND (TAB_A_RPT.pay_prd_id =
               CASE '201202'
                  WHEN 'YYYYMM'
                     THEN (SELECT DISTINCT pay_prd.pay_prd_id
                                      FROM pay_prd
                                     WHERE pay_prd.stat_cd = 2)
                  ELSE TO_NUMBER ('201202', '999999')
               END
    And its explain plan is...
    Plan
    SELECT STATEMENT ALL_ROWS Cost: 79 K Bytes: 641 M Cardinality: 3 M
    18 HASH JOIN Cost: 79 K Bytes: 641 M Cardinality: 3 M
    3 PART JOIN FILTER CREATE SYS.:BF0000 Cost: 7 K Bytes: 72 M Cardinality: 3 M
    2 PARTITION RANGE ALL Cost: 7 K Bytes: 72 M Cardinality: 3 M Partition #: 3 Partitions accessed #1 - #1048575
    1 TABLE ACCESS FULL TABLE TAB_D_RPT Cost: 7 K Bytes: 72 M Cardinality: 3 M Partition #: 3 Partitions accessed #1 - #1048575
    17 HASH JOIN Cost: 57 K Bytes: 182 M Cardinality: 874 K
    14 PART JOIN FILTER CREATE SYS.:BF0001 Cost: 38 K Bytes: 87 M Cardinality: 914 K
    13 HASH JOIN Cost: 38 K Bytes: 87 M Cardinality: 914 K
    6 PART JOIN FILTER CREATE SYS.:BF0002 Cost: 8 K Bytes: 17 M Cardinality: 939 K
    5 PARTITION RANGE ALL Cost: 8 K Bytes: 17 M Cardinality: 939 K Partition #: 9 Partitions accessed #1 - #1048575
    4 TABLE ACCESS FULL TABLE TAB_C_RPT Cost: 8 K Bytes: 17 M Cardinality: 939 K Partition #: 9 Partitions accessed #1 - #1048575
    12 HASH JOIN Cost: 24 K Bytes: 74 M Cardinality: 957 K
    7 INDEX FAST FULL SCAN INDEX (UNIQUE) TAB_B_RPT_PK Cost: 675 Bytes: 10 M Cardinality: 941 K
    11 PARTITION RANGE SINGLE Cost: 18 K Bytes: 65 M Cardinality: 970 K Partition #: 13 Partitions accessed #KEY(AP)
    10 TABLE ACCESS FULL TABLE TAB_A_RPT Cost: 18 K Bytes: 65 M Cardinality: 970 K Partition #: 13 Partitions accessed #KEY(AP)
    9 HASH UNIQUE Cost: 4 Bytes: 14 Cardinality: 2
    8 TABLE ACCESS FULL TABLE PAY_PRD Cost: 3 Bytes: 14 Cardinality: 2
    16 PARTITION RANGE JOIN-FILTER Cost: 8 K Bytes: 106 M Cardinality: 939 K Partition #: 17 Partitions accessed #:BF0001
    15 TABLE ACCESS FULL TABLE TAB_C_RPT Cost: 8 K Bytes: 106 M Cardinality: 939 K Partition #: 17 Partitions accessed #:BF0001
    Thanks Again.

  • Fact and dimension table partition

    My team is implementing new data-warehouse. I would like to know that when  should we plan to do partition of fact and dimension table, before data comes in or after?

    Hi,
    It is recommended to partition Fact table (Where we will have huge data). Automate the partition so that each day it will create a new partition to hold latest data (Split the previous partition into 2). Best practice is to create partition on transaction
    timestamps so load the incremental data into a empty table called (Table_IN) and then Switch that data into main table (Table). Make sure your tables (Table and Table_IN) should be on one file group.
    Refer below content for detailed info
    Designing and Administrating Partitions in SQL Server 2012
    A popular method of better managing large and active tables and indexes is the use of partitioning. Partitioning is a feature for segregating I/O workload within
    SQL Server database so that I/O can be better balanced against available I/O subsystems while providing better user response time, lower I/O latency, and faster backups and recovery. By partitioning tables and indexes across multiple filegroups, data retrieval
    and management is much quicker because only subsets of the data are used, meanwhile ensuring that the integrity of the database as a whole remains intact.
    Tip
    Partitioning is typically used for administrative or certain I/O performance scenarios. However, partitioning can also speed up some queries by enabling
    lock escalation to a single partition, rather than to an entire table. You must allow lock escalation to move up to the partition level by setting it with either the Lock Escalation option of Database Options page in SSMS or by using the LOCK_ESCALATION option
    of the ALTER TABLE statement.
    After a table or index is partitioned, data is stored horizontally across multiple filegroups, so groups of data are mapped to individual partitions. Typical
    scenarios for partitioning include large tables that become very difficult to manage, tables that are suffering performance degradation because of excessive I/O or blocking locks, table-centric maintenance processes that exceed the available time for maintenance,
    and moving historical data from the active portion of a table to a partition with less activity.
    Partitioning tables and indexes warrants a bit of planning before putting them into production. The usual approach to partitioning a table or index follows these
    steps:
    1. Create
    the filegroup(s) and file(s) used to hold the partitions defined by the partitioning scheme.
    2. Create
    a partition function to map the rows of the table or index to specific partitions based on the values in a specified column. A very common partitioning function is based on the creation date of the record.
    3. Create
    a partitioning scheme to map the partitions of the partitioned table to the specified filegroup(s) and, thereby, to specific locations on the Windows file system.
    4. Create
    the table or index (or ALTER an existing table or index) by specifying the partition scheme as the storage location for the partitioned object.
    Although Transact-SQL commands are available to perform every step described earlier, the Create Partition Wizard makes the entire process quick and easy through
    an intuitive point-and-click interface. The next section provides an overview of using the Create Partition Wizard in SQL Server 2012, and an example later in this section shows the Transact-SQL commands.
    Leveraging the Create Partition Wizard to Create Table and Index Partitions
    The Create Partition Wizard can be used to divide data in large tables across multiple filegroups to increase performance and can be invoked by right-clicking
    any table or index, selecting Storage, and then selecting Create Partition. The first step is to identify which columns to partition by reviewing all the columns available in the Available Partitioning Columns section located on the Select a Partitioning Column
    dialog box, as displayed in Figure 3.13. This screen also includes additional options such as the following:
    Figure 3.13. Selecting a partitioning column.
    The next screen is called Select a Partition Function. This page is used for specifying the partition function where the data will be partitioned. The options
    include using an existing partition or creating a new partition. The subsequent page is called New Partition Scheme. Here a DBA will conduct a mapping of the rows selected of tables being partitioned to a desired filegroup. Either a new partition scheme should
    be used or a new one needs to be created. The final screen is used for doing the actual mapping. On the Map Partitions page, specify the partitions to be used for each partition and then enter a range for the values of the partitions. The
    ranges and settings on the grid include the following:
    Note
    By opening the Set Boundary Values dialog box, a DBA can set boundary values based on dates (for example, partition everything in a column after a specific
    date). The data types are based on dates.
    Designing table and index partitions is a DBA task that typically requires a joint effort with the database development team. The DBA must have a strong understanding
    of the database, tables, and columns to make the correct choices for partitioning. For more information on partitioning, review Books Online.
    Enhancements to Partitioning in SQL Server 2012
    SQL Server 2012 now supports as many as 15,000 partitions. When using more than 1,000 partitions, Microsoft recommends that the instance of SQL Server have at
    least 16Gb of available memory. This recommendation particularly applies to partitioned indexes, especially those that are not aligned with the base table or with the clustered index of the table. Other Data Manipulation Language statements (DML) and Data
    Definition Language statements (DDL) may also run short of memory when processing on a large number of partitions.
    Certain DBCC commands may take longer to execute when processing a large number of partitions. On the other hand, a few DBCC commands can be scoped to the partition
    level and, if so, can be used to perform their function on a subset of data in the partitioned table.
    Queries may also benefit from a new query engine enhancement called partition elimination. SQL Server uses partition enhancement automatically if it is available.
    Here’s how it works. Assume a table has four partitions, with all the data for customers whose names begin with R, S, or T in the third partition. If a query’s WHERE clause
    filters on customer name looking for ‘System%’, the query engine knows that it needs only to partition three to answer
    the request. Thus, it might greatly reduce I/O for that query. On the other hand, some queries might take longer if there are more than 1,000 partitions and the query is not able to perform partition elimination.
    Finally, SQL Server 2012 introduces some changes and improvements to the algorithms used to calculate partitioned index statistics. Primarily, SQL Server 2012
    samples rows in a partitioned index when it is created or rebuilt, rather than scanning all available rows. This may sometimes result in somewhat different query behavior compared to the same queries running on SQL Server 2012.
    Administrating Data Using Partition Switching
    Partitioning is useful to access and manage a subset of data while losing none of the integrity of the entire data set. There is one limitation, though. When
    a partition is created on an existing table, new data is added to a specific partition or to the default partition if none is specified. That means the default partition might grow unwieldy if it is left unmanaged. (This concept is similar to how a clustered
    index needs to be rebuilt from time to time to reestablish its fill factor setting.)
    Switching partitions is a fast operation because no physical movement of data takes place. Instead, only the metadata pointers to the physical data are altered.
    You can alter partitions using SQL Server Management Studio or with the ALTER TABLE...SWITCH
    Transact-SQL statement. Both options enable you to ensure partitions are
    well maintained. For example, you can transfer subsets of data between partitions, move tables between partitions, or combine partitions together. Because the ALTER TABLE...SWITCH statement
    does not actually move the data, a few prerequisites must be in place:
    • Partitions must use the same column when switching between two partitions.
    • The source and target table must exist prior to the switch and must be on the same filegroup, along with their corresponding indexes,
    index partitions, and indexed view partitions.
    • The target partition must exist prior to the switch, and it must be empty, whether adding a table to an existing partitioned table
    or moving a partition from one table to another. The same holds true when moving a partitioned table to a nonpartitioned table structure.
    • The source and target tables must have the same columns in identical order with the same names, data types, and data type attributes
    (length, precision, scale, and nullability). Computed columns must have identical syntax, as well as primary key constraints. The tables must also have the same settings for ANSI_NULLS and QUOTED_IDENTIFIER properties.
    Clustered and nonclustered indexes must be identical. ROWGUID properties
    and XML schemas must match. Finally, settings for in-row data storage must also be the same.
    • The source and target tables must have matching nullability on the partitioning column. Although both NULL and NOT
    NULL are supported, NOT
    NULL is strongly recommended.
    Likewise, the ALTER TABLE...SWITCH statement
    will not work under certain circumstances:
    • Full-text indexes, XML indexes, and old-fashioned SQL Server rules are not allowed (though CHECK constraints
    are allowed).
    • Tables in a merge replication scheme are not allowed. Tables in a transactional replication scheme are allowed with special caveats.
    Triggers are allowed on tables but must not fire during the switch.
    • Indexes on the source and target table must reside on the same partition as the tables themselves.
    • Indexed views make partition switching difficult and have a lot of extra rules about how and when they can be switched. Refer to
    the SQL Server Books Online if you want to perform partition switching on tables containing indexed views.
    • Referential integrity can impact the use of partition switching. First, foreign keys on other tables cannot reference the source
    table. If the source table holds the primary key, it cannot have a primary or foreign key relationship with the target table. If the target table holds the foreign key, it cannot have a primary or foreign key relationship with the source table.
    In summary, simple tables can easily accommodate partition switching. The more complexity a source or target table exhibits, the more likely that careful planning
    and extra work will be required to even make partition switching possible, let alone efficient.
    Here’s an example where we create a partitioned table using a previously created partition scheme, called Date_Range_PartScheme1.
    We then create a new, nonpartitioned table identical to the partitioned table residing on the same filegroup. We finish up switching the data from the partitioned table into the nonpartitioned table:
    CREATE TABLE TransactionHistory_Partn1 (Xn_Hst_ID int, Xn_Type char(10)) ON Date_Range_PartScheme1 (Xn_Hst_ID) ; GO CREATE TABLE TransactionHistory_No_Partn (Xn_Hst_ID int, Xn_Type
    char(10)) ON main_filegroup ; GO ALTER TABLE TransactionHistory_Partn1 SWITCH partition1 TO TransactionHistory_No_Partn; GO
    The next section shows how to use a more sophisticated, but very popular, approach to partition switching called a sliding
    window partition.
    Example and Best Practices for Managing Sliding Window Partitions
    Assume that our AdventureWorks business is booming. The sales staff, and by extension the AdventureWorks2012 database, is very busy. We noticed over time that
    the TransactionHistory table is very active as sales transactions are first entered and are still very active over their first month in the database. But the older the transactions are, the less activity they see. Consequently, we’d like to automatically group
    transactions into four partitions per year, basically containing one quarter of the year’s data each, in a rolling partitioning. Any transaction older than one year will be purged or archived.
    The answer to a scenario like the preceding one is called a sliding window partition because
    we are constantly loading new data in and sliding old data over, eventually to be purged or archived. Before you begin, you must choose either a LEFT partition function window or a RIGHT partition function window:
    1. How
    data is handled varies according to the choice of LEFT or RIGHT partition function window:
    • With a LEFT strategy, partition1 holds the oldest data (Q4 data), partition2 holds data that is 6- to 9-months old (Q3), partition3
    holds data that is 3- to 6-months old (Q2), and partition4 holds recent data less than 3-months old.
    • With a RIGHT strategy, partition4 holds the holds data (Q4), partition3 holds Q3 data, partition2 holds Q2 data, and partition1
    holds recent data.
    • Following the best practice, make sure there are empty partitions on both the leading edge (partition0) and trailing edge (partition5)
    of the partition.
    • RIGHT range functions usually make more sense to most people because it is natural for most people to to start ranges at their lowest
    value and work upward from there.
    2. Assuming
    that a RIGHT partition function windows is used, we first use the SPLIT subclause of the ALTER PARTITION FUNCTIONstatement
    to split empty partition5 into two empty partitions, 5 and 6.
    3. We
    use the SWITCH subclause
    of ALTER TABLE to
    switch out partition4 to a staging table for archiving or simply to drop and purge the data. Partition4 is now empty.
    4. We
    can then use MERGE to
    combine the empty partitions 4 and 5, so that we’re back to the same number of partitions as when we started. This way, partition3 becomes the new partition4, partition2 becomes the new partition3, and partition1 becomes the new partition2.
    5. We
    can use SWITCH to
    push the new quarter’s data into the spot of partition1.
    Tip
    Use the $PARTITION system
    function to determine where a partition function places values within a range of partitions.
    Some best practices to consider for using a slide window partition include the following:
    • Load newest data into a heap, and then add indexes after the load is finished. Delete oldest data or, when working with very large
    data sets, drop the partition with the oldest data.
    • Keep an empty staging partition at the leftmost and rightmost ends of the partition range to ensure that the partitions split when
    loading in new data, and merge, after unloading old data, do not cause data movement.
    • Do not split or merge a partition already populated with data because this can cause severe locking and explosive log growth.
    • Create the load staging table in the same filegroup as the partition you are loading.
    • Create the unload staging table in the same filegroup as the partition you are deleting.
    • Don’t load a partition until its range boundary is met. For example, don’t create and load a partition meant to hold data that is
    one to two months older before the current data has aged one month. Instead, continue to allow the latest partition to accumulate data until the data is ready for a new, full partition.
    • Unload one partition at a time.
    • The ALTER TABLE...SWITCH statement
    issues a schema lock on the entire table. Keep this in mind if regular transactional activity is still going on while a table is being partitioned.
    Thanks Shiven:) If Answer is Helpful, Please Vote

  • Global Index on several partitions with each partition on different servers

    Hi,
    I have a table divided into 4 partitions. Each partition is on a different server. Currenlty the indexes are set per partition. I would like to create a global index which would work on all partitions. How could I create global index which will work on all 4 partitions/servers ? (My support team is telling me that it is not possible with different servers. It only works for several partitions on 1 physical server. Is it true ?)
    Thanks,
    Nicolas

    harry76 wrote:
    Hi,
    Are you sure this is an Oracle database. I think SQL Server has this kind of architecture in some cases?
    Not quite - in SQL Server a single instance can control multiple databases and a partitioned object can have different partitions in different databases; but the SQL Server partitioning strategy is always the equivalent of "local partitioned indexes".
    Maybe this system is using partitioned views. It is possible to create clone table structures with disjoint data sets across multiple databases and then create a UNION ALL view of the tables with a predicate on each query block identifying the data in each database. The optimizer can then do "partition elimination" if your query specifies the column(s) used in the defining predicates.
    Regards
    Jonathan Lewis

  • Partitioning suggestion?

    I am working on Oracle 11gR2 2 node RAC(OLAP database) in Linux.
    I have a huge table (estimated to be around 300G) which I need to partition. Still on the designing phase so the table doesn't exist.
    The reporting queries will be looking at data for a specific day or month, but the problem here is since the database is global we will have users querying from different places(different timezones) and the data reported should take the timezone for the specific user into consideration. We are looking at around 50 different timings.
    We will be storing data for 24 months in this table.
    This would be an OLAP database and we are considering real time reporting, so I was thinking of having two separate tables, one table(say TABLE1) to store data for a week(as this will include heavy insertion and updation activities) and the other table(say TABLE2) which will hold data for 24 months. At the end of week, can use partition exchange to merge the tables.
    I was thinking of paritioning by week, but the problem is due to timezone differences, I need to query multiple partitions even to get 1 day's worth of data and a few queries which need recent week's data wouldn't be satisfied by TABLE1 and I need to query TABLE2 also.
    To give an estimate of the table size it would be growing at 300M per day.
    Any suggestions on what would be the best partitoning strategy here?

    Firstly, I would like to thank you guys for your interest on this question.
    When I say real time, I need to report on data that was generated 2 minutes ago, so the ETL processes have to run every 2 minutes and need to complete within a minute or so.
    We would be using streams to get the data from OLTP database on which the ETL queries would be running.
    Reports are of different types, the most common ones are daily(reports on every days data upto 5PM for that timezone), interim(any data from 5PM cut off till current time less 2mins) and monthly(monthly data from beginning upto end of the month).
    Now you can say that the real time data can be kept separate and other ETL can run every hour or so, but even for daily reports if user queries at 5.02PM for his timezone I need to report the earlier days data upto 5PM which means it also real time, also holds the same for monthly reports which need to be real time when the new months starts. So the ETL has to run every 2 mins.
    This is the reason I was thinking of having 2 separate tables, one which would hold 1 week data and the other table would hold rest of data for 24 months. The reason for having first week data separate is this would have heavy inserts and updates happening during first week which means this wouldn't be heavily indexed whereas the other data would see DML activities happening rarely, so they would be heavily indexes for optimum read performance.
    These reports are scheduled, but a user can run them in an ad hoc manner too whenever he likes but we won't be looking at many concurrent users, probably 4 to 5 reports running concurrently which might not be the case too mostly but to look at worst case scenarios there might be around 10 people running reports concurrently though the actual user count would be around 5000.
    There will be almost 10000 reports running daily of which around 5000 would be scheduled daily reports. Scheduled daily reports will be cached for a week. Scheduled monthly reports will be cached for 6 months. If there are any changes to the data, cached reports will be invalid and the reports need to be run again.
    Reports would be pre-written with parameters. Ad hoc reporting is very rare, once in a couple of months.
    Daily reports dont aggregate data much, would be selecting data for that specific day which the user has access to(he has access only to local data), so yes it is quite selective without much aggregates. The amount of data generated by a daily report would be around 2-3M and would involve 7500 rows.
    Interim reports pull the same data as that of daily reports but they would report data from the cut off time(5Pm everyday) till current time.
    Monthly reports involve more aggregated data. The number of rows would be in few hundreds and the size would be few hundred KB.
    Regarding the indexes, I was looking at local paritioned indexes for easy maintenance.
    Can you please eleborate a bit on this -
    Have you worked out how you can write a query which accepts an input from one timezone and does partition elimination against a table partitioned on one of the timestamp datatypes (or even partitioned on a simple date data type).
    The table would be having a date column, so I was thinking of converting the time the query was received to the timezone of that specific user and comparing the time with the date column. Will this be ok or am I missing something here?

  • Hash partitioning v. list partitioning on surrogate key + partition pruning

    Hi,
    Have a large fact table with surrogate keys, therefore queries are of form
    select dimension.attribute..
    from fact, dima, dimb..
    where facta.dima_surrogate_key = dima.dimension_key
    and facta.dimb_surrogate_key = dimb.dimension_key
    and dima.attribute = <value>
    and dimb.attribute = <value>
    Would ideally like partition pruning to happen but will this happen if hash partition on facta.surrogate_key
    Likewise could list partition on facta.dima_surrogate_key and further sub-partition on hash of factb.dima_surrogate_key.
    Any advice much appreciated.

    user5716448 wrote:
    Hi,
    Version 11.2.0.1
    fact table structure
    PRODUCT_ID NUMBER
    RETAILER_ID NUMBER
    OUTLET_ID NUMBER
    CALENDAR_ID NUMBER
    BRANCH_ID NUMBER
    PUBLISHER_ID NUMBER
    DISTRIBUTOR_ID NUMBER
    TRANS_TYPE_ID NUMBER
    TRANS_QTY NUMBER (10)
    TRANS_VALUE (10,4)
    No date on fact table (just surrogate_id for calendar whihc links to calendar/date dimension.
    Although queries can be by date of transaction, most aren't.
    Potential to grow to 3 billion rows.
    Considering hash partitioning on the product_id, simply to break data down and product_id is the largest dimension.About hash partitioning – in this case it is probably all about the ability to run in parallel. Do not have any info on that, so I cannot comment further.
    >
    sqls are varied, lots of different types some query all dimensions, sometimes a few. Not the straightforward date examples in the manual.You can pick a dimension that is frequently used by the SQLs. I understand that there is no perfect one, but even if you pick just a “good” one you might have a good deal of partition elimination.
    >
    Users run 3rd part ad-hoc reporting layer which has to allow them to report against the star in any way they want.
    Star transformation hint enabled. Have heard in deciding number of hash partitions, partition size should geneerally be < 2gb.
    e.g transactions for a given product for customers belonging to a given multiple in a given week
    select trans_qty, trans_value, m.prod_name, m.prod_num, r.cust_name, w.branch_name, rtt.trans_date, rtt,trans_type
    from retailer_transaction rt, media m, wholesaler w, calendar c, retailer r, trans_type rtt
    where rt.issue_id = m.dimension_key
    and m.prod_num = 600
    and rt.branch_id = w.dimension_key
    and rt.outlet_id = r.dimension_key
    and r.multiple_num = 700
    and rt.calendar_id = calendar.dimension_key
    and m.issue_year_week = 201110
    and rt.trans_type_id = rtt.dimension_keyLastly, you need to focus on weather and how to partition your indexes (I assume you have bunch of bitmaps). This decision is at least as important as partitioning the table.

  • IOT or Hash partition

    Hi all,
    I want to insert large data into a table to be retreived later using a key column (like emp no).
    To the performance point of view, which is more efficient: IOT (Index Organized Table) or Hash Partition ?

    I highly appreciate your time Justin. Your explanation clarified many things to me.
    However, I have small notes on your comments:
    Firt:
    <<IOT's tend to be useful when you have thin, tall tables (many rows, few columns) where you always want to retrieve all the rows.>>
    Regarding this claim, I referred to the following sources:
    1. Sybex-Oracle9i Performance Tuning book
    "If you access the table using its primary key, an IOT will return the rows more quickly than a traditional table."
    2. http://www.tlingua.com/articles/iot.html
    For single row fetch,"IOTs could provide a substantial performance gain as well as reducing the demand for disk drives"
    For Index Range Scans,"IOTs significantly outperform the standard B-tree/table model during index range scans."
    3. Oracle9i Database Administrator’s Guide Release 2 (9.2)
    "Index-organized tables are particularly useful when you are using applications that must retrieve data based on a primary key."
    As you can see Justin, none of them mentioned the thin-tall-table fact. Did you obtain it from practical experience or from some source?
    Also they all showed that IOT is most useful when retreiving based on PK.
    Second:
    "In general, partitioning works best when you are doing set-based processing where you can use partition elimination to concentrate on a particular subset of the data."
    In Sybex-Oracle9i Performance Tuning book it is stated that "Hash partitions work best when applications retrieve the data from the partitioned table via the unique key. Range lookups on hash partitioned tables derive no benefit from the partitioning.".
    I can see there is some confilict, isn't it?
    Thanks in advance.

  • Partitioned table tuning help

    Hi,
    Below query is taking huge time for returning result(28579 rows 9 mins).IN this query table audit table is partitioned .Here i'm suspecting count (*)is main problem.I'm taking count for pagination, i'm displaying each page 100 rows based on count only i have to do pg nation ..Here year is range partitioned and month is LIST partitioned .Here year,month,school_code and auidt_date only mandatory params rest of them optional.Please advice to improve the performance
    Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64biQuery
    SELECT ia.*--,rank() over(order by year)
      ,COUNT(year) OVER() AS record_count
    -- ROWNUM          AS row_num
    FROM IBAUDIT.ibis_audit ia
    WHERE YEAR = 2012
    AND MONTH  = 'MAY'
    AND audit_date BETWEEN to_date('04/04/2012','dd-mm-yyyy') AND to_date('04/04/2013','dd-mm-yyyy')
    AND school                                                     = '000008'
    AND (:i_candidate                                             IS NULL
    OR candidate                                                   = :i_candidate)
    AND (:i_user                                                  IS NULL
    OR person_code                                                 = :i_user)
    AND (:i_person                                                IS NULL
    OR active_person_code                                          = :i_person)
    AND (:i_element                                               IS NULL
    OR element                                                     = :i_element)
    AND (:i_action                                                IS NULL
    OR DECODE(action, 'INSERT', 'ADD', 'UPDATE', 'CHANGE', action) = UPPER(:i_action))
    AND EXISTS
      (SELECT 1
      FROM IBIS.subject_component sc
      WHERE sc.year           = 2012
      AND sc.month            = 'MAY'
      AND sc.paper_code       = ia.paper_code
      AND (:i_subject        IS NULL
      OR sc.subject           = :i_subject)
      AND (:i_subject_option IS NULL
      OR sc.subject_option    = :i_subject_option)
      AND (:i_lvl            IS NULL
      OR sc.lvl               = :i_lvl)
      AND (:i_component      IS NULL
      OR sc.component         = :i_component)
      explan
    line 1: SQLPLUS Command Skipped: set linesize 130
    line 2: SQLPLUS Command Skipped: set pagesize 0
    PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                           
    Plan hash value: 2770926248                                                                                                                                                                                                                                                                                 
    | Id  | Operation                            | Name                          | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |                                                                                                                                                                      
    |   0 | SELECT STATEMENT                     |                               |     1 |   369 |  2601  (28)| 00:00:23 |       |       |                                                                                                                                                                      
    |   1 |  WINDOW BUFFER                       |                               |     1 |   369 |  2601  (28)| 00:00:23 |       |       |                                                                                                                                                                      
    |*  2 |   TABLE ACCESS BY LOCAL INDEX ROWID  | IBIS_AUDIT                    |     1 |   294 |  2601  (28)| 00:00:23 |   181 |   181 |                                                                                                                                                                      
    |   3 |    NESTED LOOPS                      |                               |     1 |   369 |  2601  (28)| 00:00:23 |       |       |                                                                                                                                                                      
    |   4 |     SORT UNIQUE                      |                               |     1 |    75 |    44   (0)| 00:00:01 |       |       |                                                                                                                                                                      
    |*  5 |      TABLE ACCESS BY INDEX ROWID     | SUBJECT_COMPONENT             |     1 |    75 |    44   (0)| 00:00:01 |       |       |                                                                                                                                                                      
    |*  6 |       INDEX RANGE SCAN               | SUBJECT_COMPONENT_ASSESS_TYPE |  1131 |       |     8   (0)| 00:00:01 |       |       |                                                                                                                                                                      
    |   7 |     PARTITION RANGE SINGLE           |                               |       |       |            |          |    37 |    37 |                                                                                                                                                                      
    |   8 |      PARTITION LIST SINGLE           |                               |       |       |            |          |   KEY |   KEY |                                                                                                                                                                      
    |   9 |       BITMAP CONVERSION TO ROWIDS    |                               |       |       |            |          |       |       |                                                                                                                                                                      
    |  10 |        BITMAP AND                    |                               |       |       |            |          |       |       |                                                                                                                                                                      
    |  11 |         BITMAP CONVERSION FROM ROWIDS|                               |       |       |            |          |       |       |                                                                                                                                                                      
    |* 12 |          INDEX RANGE SCAN            | IBIS_AUDIT_SCHOOL             | 21826 |       |    33   (4)| 00:00:01 |   181 |   181 |                                                                                                                                                                      
    |  13 |         BITMAP CONVERSION FROM ROWIDS|                               |       |       |            |          |       |       |                                                                                                                                                                      
    |* 14 |          INDEX RANGE SCAN            | IBIS_AUDIT_PAPER              | 21826 |       |    84   (4)| 00:00:01 |   181 |   181 |                                                                                                                                                                      
    Predicate Information (identified by operation id):                                                                                                                                                                                                                                                         
       2 - filter("YEAR"=2012 AND (:I_CANDIDATE IS NULL OR "CANDIDATE"=:I_CANDIDATE) AND (:I_USER IS NULL OR                                                                                                                                                                                                    
                  "PERSON_CODE"=:I_USER) AND (:I_PERSON IS NULL OR "ACTIVE_PERSON_CODE"=:I_PERSON) AND (:I_ELEMENT IS NULL OR                                                                                                                                                                                   
                  "ELEMENT"=:I_ELEMENT) AND "AUDIT_DATE">=TO_DATE('2012-04-04 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND (:I_ACTION IS NULL OR                                                                                                                                                                     
                  DECODE("ACTION",'INSERT','ADD','UPDATE','CHANGE',"ACTION")=UPPER(:I_ACTION)) AND "AUDIT_DATE"<=TO_DATE('2013-04-04 00:00:00',                                                                                                                                                                 
                  'yyyy-mm-dd hh24:mi:ss') AND "SC"."YEAR"="IA"."YEAR" AND "SC"."MONTH"="IA"."MONTH")                                                                                                                                                                                                           
       5 - filter((:I_SUBJECT_OPTION IS NULL OR "SC"."SUBJECT_OPTION"=:I_SUBJECT_OPTION) AND (:I_SUBJECT IS NULL OR                                                                                                                                                                                             
                  "SC"."SUBJECT"=:I_SUBJECT) AND (:I_COMPONENT IS NULL OR "SC"."COMPONENT"=:I_COMPONENT) AND ("SC"."LVL"=:I_LVL OR :I_LVL IS                                                                                                                                                                    
                  NULL))                                                                                                                                                                                                                                                                                        
       6 - access("SC"."YEAR"=2012 AND "SC"."MONTH"='MAY')                                                                                                                                                                                                                                                      
      12 - access("SCHOOL"='000008')                                                                                                                                                                                                                                                                            
      14 - access("SC"."PAPER_CODE"="IA"."PAPER_CODE")                                                                                                                                                                                                                                                          
    36 rows selected

    user575115 wrote:
    Hi,
    Below query is taking huge time for returning result(28579 rows 9 mins).IN this query table audit table is partitioned .Here i'm suspecting count (*)is main problem.I'm taking count for pagination, i'm displaying each page 100 rows based on count only i have to do pg nation ..Here year is range partitioned and month is LIST partitioned .Here year,month,school_code and auidt_date only mandatory params rest of them optional.Please advice to improve the performance
    Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64biQuery
    SELECT ia.*--,rank() over(order by year)
    ,COUNT(year) OVER() AS record_count
    -- ROWNUM          AS row_num
    FROM IBAUDIT.ibis_audit ia
    WHERE YEAR = 2012
    AND MONTH  = 'MAY'
    AND audit_date BETWEEN to_date('04/04/2012','dd-mm-yyyy') AND to_date('04/04/2013','dd-mm-yyyy')
    AND school                                                     = '000008'
    AND (:i_candidate                                             IS NULL
    OR candidate                                                   = :i_candidate)
    AND (:i_user                                                  IS NULL
    OR person_code                                                 = :i_user)
    AND (:i_person                                                IS NULL
    OR active_person_code                                          = :i_person)
    AND (:i_element                                               IS NULL
    OR element                                                     = :i_element)
    AND (:i_action                                                IS NULL
    OR DECODE(action, 'INSERT', 'ADD', 'UPDATE', 'CHANGE', action) = UPPER(:i_action))
    AND EXISTS
    (SELECT 1
    FROM IBIS.subject_component sc
    WHERE sc.year           = 2012
    AND sc.month            = 'MAY'
    AND sc.paper_code       = ia.paper_code
    AND (:i_subject        IS NULL
    OR sc.subject           = :i_subject)
    AND (:i_subject_option IS NULL
    OR sc.subject_option    = :i_subject_option)
    AND (:i_lvl            IS NULL
    OR sc.lvl               = :i_lvl)
    AND (:i_component      IS NULL
    OR sc.component         = :i_component)
    );explan
    PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                           
    Plan hash value: 2770926248                                                                                                                                                                                                                                                                                 
    | Id  | Operation                            | Name                          | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |                                                                                                                                                                      
    |   0 | SELECT STATEMENT                     |                               |     1 |   369 |  2601  (28)| 00:00:23 |       |       |                                                                                                                                                                      
    |   1 |  WINDOW BUFFER                       |                               |     1 |   369 |  2601  (28)| 00:00:23 |       |       |                                                                                                                                                                      
    |*  2 |   TABLE ACCESS BY LOCAL INDEX ROWID  | IBIS_AUDIT                    |     1 |   294 |  2601  (28)| 00:00:23 |   181 |   181 |                                                                                                                                                                      
    |   3 |    NESTED LOOPS                      |                               |     1 |   369 |  2601  (28)| 00:00:23 |       |       |                                                                                                                                                                      
    |   4 |     SORT UNIQUE                      |                               |     1 |    75 |    44   (0)| 00:00:01 |       |       |                                                                                                                                                                      
    |*  5 |      TABLE ACCESS BY INDEX ROWID     | SUBJECT_COMPONENT             |     1 |    75 |    44   (0)| 00:00:01 |       |       |                                                                                                                                                                      
    |*  6 |       INDEX RANGE SCAN               | SUBJECT_COMPONENT_ASSESS_TYPE |  1131 |       |     8   (0)| 00:00:01 |       |       |                                                                                                                                                                      
    |   7 |     PARTITION RANGE SINGLE           |                               |       |       |            |          |    37 |    37 |                                                                                                                                                                      
    |   8 |      PARTITION LIST SINGLE           |                               |       |       |            |          |   KEY |   KEY |                                                                                                                                                                      
    |   9 |       BITMAP CONVERSION TO ROWIDS    |                               |       |       |            |          |       |       |                                                                                                                                                                      
    |  10 |        BITMAP AND                    |                               |       |       |            |          |       |       |                                                                                                                                                                      
    |  11 |         BITMAP CONVERSION FROM ROWIDS|                               |       |       |            |          |       |       |                                                                                                                                                                      
    |* 12 |          INDEX RANGE SCAN            | IBIS_AUDIT_SCHOOL             | 21826 |       |    33   (4)| 00:00:01 |   181 |   181 |                                                                                                                                                                      
    |  13 |         BITMAP CONVERSION FROM ROWIDS|                               |       |       |            |          |       |       |                                                                                                                                                                      
    |* 14 |          INDEX RANGE SCAN            | IBIS_AUDIT_PAPER              | 21826 |       |    84   (4)| 00:00:01 |   181 |   181 |                                                                                                                                                                      
    Predicate Information (identified by operation id):                                                                                                                                                                                                                                                         
    2 - filter("YEAR"=2012 AND (:I_CANDIDATE IS NULL OR "CANDIDATE"=:I_CANDIDATE) AND (:I_USER IS NULL OR                                                                                                                                                                                                    
    "PERSON_CODE"=:I_USER) AND (:I_PERSON IS NULL OR "ACTIVE_PERSON_CODE"=:I_PERSON) AND (:I_ELEMENT IS NULL OR                                                                                                                                                                                   
    "ELEMENT"=:I_ELEMENT) AND "AUDIT_DATE">=TO_DATE('2012-04-04 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND (:I_ACTION IS NULL OR                                                                                                                                                                     
    DECODE("ACTION",'INSERT','ADD','UPDATE','CHANGE',"ACTION")=UPPER(:I_ACTION)) AND "AUDIT_DATE"<=TO_DATE('2013-04-04 00:00:00',                                                                                                                                                                 
    'yyyy-mm-dd hh24:mi:ss') AND "SC"."YEAR"="IA"."YEAR" AND "SC"."MONTH"="IA"."MONTH")                                                                                                                                                                                                           
    5 - filter((:I_SUBJECT_OPTION IS NULL OR "SC"."SUBJECT_OPTION"=:I_SUBJECT_OPTION) AND (:I_SUBJECT IS NULL OR                                                                                                                                                                                             
    "SC"."SUBJECT"=:I_SUBJECT) AND (:I_COMPONENT IS NULL OR "SC"."COMPONENT"=:I_COMPONENT) AND ("SC"."LVL"=:I_LVL OR :I_LVL IS                                                                                                                                                                    
    NULL))                                                                                                                                                                                                                                                                                        
    6 - access("SC"."YEAR"=2012 AND "SC"."MONTH"='MAY')                                                                                                                                                                                                                                                      
    12 - access("SCHOOL"='000008')                                                                                                                                                                                                                                                                            
    14 - access("SC"."PAPER_CODE"="IA"."PAPER_CODE")                                                                                                                                                                                                                                                          
    36 rows selected
    Plan operations look okay although the Nested Loops operation in step 3 looks out of place - would a hash join work better with the bitmaps? Partition elimination looks great! The series of 1 values at the top of the plan in steps 0-4 suggests something is wrong with either the statistics or the optimizer's processing of the query; you are really getting a lot more rows than the optimizer is estimating.
    You reported the query runs faster without the COUNT() which you need. How much faster?
    AND and OR conditions mixed together in WHERE clause can add overhead. Would using NVL() instead of the AND/OR combinations affect performance (beware index supression)?
    The estimated statistics disappear reading the plan from bottom to the top in step 11. Are all of the objects in the plan - tables and indexes both - analyzed with current values? In particular the # of rows in step 2 for IBIS_AUDIT looks odd - 1 row (possibly correct)? Similarly the estimated values ifor the index lookup in step 5 look low.
    If necessary a materialized view with automatic query rewrite (provided that this works) is an option but tuning the SQL is a better idea.

  • Partition Eliminiation on views and joins with other partitioned tables

    I have a bunch of tables that are daily partioned and other which are not. We constantly join all these tables. I have noticed that partition elimination doesn't happen in most cases and I want some input or pointers on these.
    Case 1
    We have a view that joins a couple of partitioned tables on the id fileds and they the partition key is timestamp with local time zone.
    TABLEA
    tableaid
    atime
    TABLEB
    tablebid
    tableaid
    btime
    The view basically joins on tableaid, a.tableaid = b.tableaid(+) and a bunch of other non partitioned tables. atime and btime are the individal partition keys in the tables and these time do not match up like the id's in other words there is a little bit of correlation but they can be very different.
    When I run a query against the view providing a time range for btime, I see partition elimination on tabled in the explain plan with KEY on Pstart/Pstop. But its a full tablescan on tablea. I was hoping there would be somekind of partition elimination here since its also partioned daily on the same datatype timestamp with local time zone.
    Case 2
    I have a couple of more partitioned tables
    TABELC
    tablecid
    tablebid
    ctime
    TABLED
    tabledid
    tablebid
    dtime
    As you can see these tables are joined with tablebid and the times here generally correlate to tableb's timestamp as well.
    Sub Case 1
    When I join these tables to the view and give a time range on btime, I see partition elimination happening on tableb but not on tablea or any of the other tables.
    Sub Case 2
    Then I got rid of the view, wrote a query that us similar to the view where I join on tableaid (tablea and tableb), then on tablebid (tableb, tablec and tabled) and a few other tables and execute the query with some time range on btime and I still see that partition elimination happens only on tableb.
    I thought that if other tables are also partitioned on a similark key that partition eliminition should happen? Or what am I missing here that is preventing from partition elimination on the other tables.

    Performance is of utmost importance and partition pruning is going to help in that. I guess that's what I'm trying to acheive.
    To achive partition elimination on tablec, d, etc I'm doing an outer join with btime and that seems to work. Also since most of the time after the partition elimination, I don't need a full tablescan since the period I will be querying most of the time will be small I also created a local index on id field that I'm using to join so that it can do a "TABLE ACCESS BY LOCAL INDEX ROWID" this way it should peform better than a global index since the index traversal path should be small when compared to the global index.
    Of couse I still have problem with the tablea not being pruned, since I cannot do an outer join on two fields in the same table (id and time). So might just include the time criteria again and may be increase the time range a little more when compared to what the actual user submitted to try not to miss those rows.
    Any suggestions is always welcome.

  • Partitioning the OKL_STRM_ELEMENTS table

    I am looking for someone with experience with partitioning the OKL_STRM_ELEMENTS table. I would like to know what you partitioned on and if you had any problems once you implemented the partitions. Besides the OKL_STRM_ELEMENTS table are there any other Lease Management table that should be partitioned.
    BLC

    This is documentation of the Partitioning the OKL_STRM_ELEMENTS table
    You should made a proposal to partition the table based on STREAM_ELEMENT_DATE Performance team however suggested creating a larger number of partitions using a smaller range (MMYYYY vs YYYY) rather than using a subpartition by hash(ID).
    Performance benefits may be seen in SQL statements that take advantage of the partioning scheme resulting in partition elimination (i.e. the sqls actually scan less data), this happens for sqls that have the partition key in the WHERE clause.
    Partitioning a table can actually degrade overall performance if the SQL statements referencing this table do not include the partition key in the WHERE clause as a filter. The performance degradation is caused by the fact that the query has to scan several partitions as opposed to a single segment in the non-partitioned case.
    The majority of select statements on OKL_STRM_ELEMENTS in OKL do include STREAM_ELEMENT_DATE in the where clause, so overall benefit should be positive.
    Moreover, ranges should be based on analysis of your data distribution

Maybe you are looking for

  • How can i organize apps on one home page?

    I have four folders of apps sprawled across four home pages with all that space in between.     How can I move them all to the front home page?    Can't find this in the manual---is there a secret? Thanks for whatever help you can provide!  

  • Exporting Final Cut timeline in highest quality Quicktime (self-contained)

    Hi, I am wondering if you can help me. I just finished editing a film in HDV, 24P in Final Cut Studio 2 and need to export it as a stand alone quicktime file to take it to the color correction people and then for downressing in order to write to Digi

  • Screen not full size with DVD movie

    I have a new iMac and played my first DVD. It was a 16:9 letter box format. The DVD started as a very small picture. I then went to view and set for full screen mode. The movie still only expanded to 70% or so of the screen. Are iMAC not capable of u

  • How to lock a user by using random password?

    hello, i need to lock a user from a target system by pushing in random passwords for the accounts. i am successfully able to create an adapter that can generate a random string, but the place where i am stuck is that where to use it as i just need to

  • How can I find the ASM port

    Hi, When I use OEM grid control to monitor the ASM, during the configuration, I was asked to enter port, SID, please tell me from which file I can find the ASM instance port information? Thanks, Hank USA 2007