Here we are going to discuss about how
Automatic indexing (AI) works in relation with partitioned objects. Oracle has
various options when indexing a partitioned table
So that question(s) are how AI handles
scenario with partitioned objects? To answer that we are going to build an
interval partitioned table with a partition for each year worth of data.
ai_demo@PDB1> create table
demo023
2 partition by range( release_dt )
3 interval ( numtoyminterval(1,'year') )
4 ( partition p2010 values less than
5 (to_date('01-jan-2011','dd-mon-yyyy')) )
6 nologging as
7 select a.*,
8 sysdate - mod(rownum,2800) as release_dt ,
9 ceil( dbms_random.value(1,500000) ) as sales_amt
10 from stage a, stage b, stage c
11 where rownum <= 10000000 ;
Table created.
We will now run the following very
selective queries based on the “sales_amt” column that is not part of
partitioning key column.
ai_demo@PDB1> select *
from demo023 where sales_amt = 55;
25 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3128466500
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 2160 | 46565 (1)| 00:00:02 | | |
| 1 | PARTITION RANGE ALL | | 20 | 2160 | 46565 (1)| 00:00:02 | 1 |1048575|
|* 2 | TABLE ACCESS STORAGE FULL| DEMO023 | 20 | 2160 | 46565 (1)| 00:00:02 | 1 |1048575|
------------------------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
---------------------------------------------------
2 - storage("SALES_AMT"=55)
filter("SALES_AMT"=55)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
169513 consistent gets
169495 physical reads
0 redo size
2644 bytes sent via SQL*Net to client
546 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
25 rows processed
Without an index, the CBO has no choice
but to use a Full table scan.
But what will AI make of things? If we
look at the next AI report, it shows this.
SUMMARY (AUTO INDEXES)
-------------------------------------------------------------------------------
Index candidates : 3
Indexes created (visible / invisible) : 2 (2 / 0)
Space used (visible / invisible) : 327.16 MB (327.16 MB / 0 B)
Indexes dropped : 0
SQL statements verified : 3
SQL statements improved (improvement factor) : 2 (19304.5x)
SQL plan baselines created : 0
Overall improvement factor : 16337.2x
-------------------------------------------------------------------------------
SUMMARY (MANUAL INDEXES)
-------------------------------------------------------------------------------
Unused indexes : 0
Space used : 0 B
Unusable indexes : 0
-------------------------------------------------------------------------------
INDEX DETAILS
-------------------------------------------------------------------------------
1. The following indexes were created:
*: invisible
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
| Owner | Table | Index | Key | Type | Properties |
-------------------------------------------------------------------------------
| AI_DEMO | DEMO020A | SYS_AI_6z61w0j7jqqc0 | X2 | B-TREE | NONE |
| AI_DEMO | DEMO023 | SYS_AI_g4dwbmutt3xqu | SALES_AMT | B-TREE | NONE |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Parsing Schema Name : AI_DEMO
SQL ID : 8kr62r0f9f3qc
SQL Text : select * from demo023 where sales_amt = 55
Improvement Factor : 18844.2x
Execution Statistics:
-----------------------------
Original Plan Auto Index Plan
---------------------------- ----------------------------
Elapsed Time (s): 2605642 5137
CPU Time (s): 285852 2215
Buffer Gets: 508796 28
Optimizer Cost: 46565 28
Disk Reads: 508491 27
Direct Writes: 0 0
Rows Processed: 75 25
Executions: 3 1
PLANS SECTION
---------------------------------------------------------------------------------------------
- Original
-----------------------------
Plan Hash Value : 3128466500
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 46565 | |
| 1 | PARTITION RANGE ALL | | 20 | 2160 | 46565 | 00:00:02 |
| 2 | TABLE ACCESS STORAGE FULL | DEMO023 | 20 | 2160 | 46565 | 00:00:02 |
---------------------------------------------------------------------------------
- With Auto Indexes
-----------------------------
Plan Hash Value : 1036907592
--------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 2700 | 28 | 00:00:01 |
| 1 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED | DEMO023 | 25 | 2700 | 28 | 00:00:01 |
| * 2 | INDEX RANGE SCAN | SYS_AI_g4dwbmutt3xqu
| 25 |
| 3 | 00:00:01 |
--------------------------------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
------------------------------------------
* 2 - access("SALES_AMT"=55)
Notes
-----
- Dynamic sampling used for this statement ( level = 11 )
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
We notice a couple of interesting points,
first – yes AI has created an index based on “sales_amt” column (SYS_AI_g4dwbmutt3xqu)
as it improves the performance by a reported 18844.2x. also the AI is
non-partitioned (global) index. From a performance perspective, this is the
most effective index to create to improve the performance of the query as the
CBO only has the one index structure to navigate (vs. LOCAL index that would require
having to range scan down all the index structures of each table partition)
If we look at the index details
ai_demo@PDB1> select
owner,index_name,indexing,auto,partitioned,
2 status,visibility,clustering_factor,leaf_blocks
3 from all_indexes
4 where table_name ='DEMO023'
5 and owner ='AI_DEMO';
OWNER INDEX_NAME INDEXIN AUT PAR STATUS VISIBILIT CLUSTERING_FACTOR LEAF_BLOCKS
---------- ------------------------- ------- --- --- -------- --------- ----------------- -----------
AI_DEMO SYS_AI_g4dwbmutt3xqu FULL YES NO VALID VISIBLE 9999423 21374
We noticed that it is a non-partitioned index, that is VISIBLE and VALID and can potentially used by any database session.
If we now try to run a query
ai_demo@PDB1> set
autotrace traceonly exp statistics
ai_demo@PDB1> select * from demo023 where sales_amt = 55;
25 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1036907592
-----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 2160 | 23 (0)| 00:00:01 | | |
| 1 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| DEMO023 | 20 | 2160 | 23 (0)| 00:00:01 | ROWID | ROWID |
|* 2 |
INDEX RANGE SCAN
| SYS_AI_g4dwbmutt3xqu | 20 | |
3 (0)| 00:00:01 | |
|
-----------------------------------------------------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
---------------------------------------------------
2 - access("SALES_AMT"=55)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
29 consistent gets
0
physical reads
0 redo size
2644 bytes sent via SQL*Net to client
546 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
25 rows processed
ai_demo@PDB1> set
autotrace off
we can see that the query now uses the
newly created AI and is indeed more efficient, performing now just 29 logical
IO (previously it was 169K logical IO)
- Non-partitioned index
- Globally partitioned index
- Locally partitioned index
2 partition by range( release_dt )
3 interval ( numtoyminterval(1,'year') )
4 ( partition p2010 values less than
5 (to_date('01-jan-2011','dd-mon-yyyy')) )
6 nologging as
7 select a.*,
8 sysdate - mod(rownum,2800) as release_dt ,
9 ceil( dbms_random.value(1,500000) ) as sales_amt
10 from stage a, stage b, stage c
11 where rownum <= 10000000 ;
----------------------------------------------------------
Plan hash value: 3128466500
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 2160 | 46565 (1)| 00:00:02 | | |
| 1 | PARTITION RANGE ALL | | 20 | 2160 | 46565 (1)| 00:00:02 | 1 |1048575|
|* 2 | TABLE ACCESS STORAGE FULL| DEMO023 | 20 | 2160 | 46565 (1)| 00:00:02 | 1 |1048575|
------------------------------------------------------------------------------------------------------
---------------------------------------------------
filter("SALES_AMT"=55)
----------------------------------------------------------
0 recursive calls
0 db block gets
169513 consistent gets
169495 physical reads
0 redo size
2644 bytes sent via SQL*Net to client
546 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
25 rows processed
SUMMARY (AUTO INDEXES)
-------------------------------------------------------------------------------
Index candidates : 3
Indexes created (visible / invisible) : 2 (2 / 0)
Space used (visible / invisible) : 327.16 MB (327.16 MB / 0 B)
Indexes dropped : 0
SQL statements verified : 3
SQL statements improved (improvement factor) : 2 (19304.5x)
SQL plan baselines created : 0
Overall improvement factor : 16337.2x
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Unused indexes : 0
Space used : 0 B
Unusable indexes : 0
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
1. The following indexes were created:
*: invisible
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
| Owner | Table | Index | Key | Type | Properties |
-------------------------------------------------------------------------------
| AI_DEMO | DEMO020A | SYS_AI_6z61w0j7jqqc0 | X2 | B-TREE | NONE |
| AI_DEMO | DEMO023 | SYS_AI_g4dwbmutt3xqu | SALES_AMT | B-TREE | NONE |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Parsing Schema Name : AI_DEMO
SQL ID : 8kr62r0f9f3qc
SQL Text : select * from demo023 where sales_amt = 55
Improvement Factor : 18844.2x
-----------------------------
Original Plan Auto Index Plan
---------------------------- ----------------------------
Elapsed Time (s): 2605642 5137
CPU Time (s): 285852 2215
Buffer Gets: 508796 28
Optimizer Cost: 46565 28
Disk Reads: 508491 27
Direct Writes: 0 0
Rows Processed: 75 25
Executions: 3 1
---------------------------------------------------------------------------------------------
-----------------------------
Plan Hash Value : 3128466500
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 46565 | |
| 1 | PARTITION RANGE ALL | | 20 | 2160 | 46565 | 00:00:02 |
| 2 | TABLE ACCESS STORAGE FULL | DEMO023 | 20 | 2160 | 46565 | 00:00:02 |
---------------------------------------------------------------------------------
-----------------------------
Plan Hash Value : 1036907592
| Id | Operation | Name | Rows | Bytes | Cost | Time |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 2700 | 28 | 00:00:01 |
| 1 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED | DEMO023 | 25 | 2700 | 28 | 00:00:01 |
------------------------------------------
* 2 - access("SALES_AMT"=55)
-----
- Dynamic sampling used for this statement ( level = 11 )
-------------------------------------------------------------------------------
2 status,visibility,clustering_factor,leaf_blocks
3 from all_indexes
4 where table_name ='DEMO023'
5 and owner ='AI_DEMO';
---------- ------------------------- ------- --- --- -------- --------- ----------------- -----------
AI_DEMO SYS_AI_g4dwbmutt3xqu FULL YES NO VALID VISIBLE 9999423 21374
We noticed that it is a non-partitioned index, that is VISIBLE and VALID and can potentially used by any database session.
ai_demo@PDB1> select * from demo023 where sales_amt = 55;
----------------------------------------------------------
Plan hash value: 1036907592
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 2160 | 23 (0)| 00:00:01 | | |
| 1 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| DEMO023 | 20 | 2160 | 23 (0)| 00:00:01 | ROWID | ROWID |
---------------------------------------------------
----------------------------------------------------------
0 recursive calls
0 db block gets
29 consistent gets
0 redo size
2644 bytes sent via SQL*Net to client
546 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
25 rows processed
No comments:
Post a Comment