Partitioning in Oracle 1728042170
Partitioning in Oracle 1728042170
1.TYPES OF PARTITIONS
A.TABLE_PARTITIONS
o 1)RANGE PARTITION
i)range interval
ii)reference interval
o 2)HASH PARTITION
o 3)COMPOSITE PARTITION
o 4)LIST PARTITION
B.PARTITIONED INDEXES
o 1)GLOBAL INDEXES
o 2)LOCAL INDEXES
C.PARTITION PRUNING
o 1)TYPES
o 2)CONDITIONS
o 3)EXAMPLE
D.EXTRAS
E.REFRENCE
1. TYPES OF PARTITIONS
A.TABLE PARTITIONS
1)RANGE PARTITION
Range partitioning is a convenient method for partitioning historical data. The boundaries of
range partitions define the ordering of the partitions in the tables or indexes.
Range partitioning is also ideal when you periodically load new data and purge old data, because
it is easy to add or drop partitions.
You often scan large tables using a date column like TRANSACION_DATE ,ORDER_DATE.
You need to maintain a rolling window of data.
You want to perform admin tasks like backup and restore more easily by dividing large tables
into smaller, manageable pieces based on date ranges.
i) Range Interval Partition
Interval partitioning is an extension to range partitioning in which, beyond a point in time,
partitions are defined by an interval. Interval partitions are automatically created by the database
when data is inserted into the partition.
2) HASH PARTITION
Sometimes it's unclear where data should go, even if you know the partitioning key. Instead of
grouping similar data like in range partitioning, hash partitioning randomly distributes data across
partitions using a hashing algorithm. This method can work well for certain datasets, but it may not
be effective for managing historical data.
In this definition of the table, I have "randomly" distributed incoming rows across 4 Partitions in 4
different Tablespaces. Given the incoming " transaction_date" values ,Each of the 4 Partitions would
be equally loaded.
3) Composite Partition
a) Range-Hash
b) Range-List
c) Range-Range
d) List-Range
e) List-Hash
f) List-List
g) Interval-Hash
h) Interval-List
i) Interval-Range
4) LIST PARTITION
You should use list partitioning when you want to specifically map rows to partitions based on
discrete values.
Unlike range and hash partitioning, multi-column partition keys are not supported for list
partitioning. If a table is partitioned by list, the partitioning key can only consist of a single column of
the table.
B.PARTITIONED INDEXES:-
1.GLOBAL INDEX
i)Global partitioned
An index that is partitioned independently of the underlying table partitions. This allows for more
flexible data management. There will be multiple segment for global partitioned index.We can
create multiple partitions as much as we want .It is independent of table partitions.
Means if table has 32 partitions then we can create no of index partitions as per our choice.
Below we are trying to create global partition index but we got error because we have specified
Range for partition and it is not covering whole table hence me met with below error.
ERROR at line 5:
ORA-14021: MAXVALUE must be specified for all columns
Index created.
Index created.
Also if you try to create global partition index on column other than partition column you will end
with below error. GLOBAL non-prefixed partitioned index are not supported by oracle. If you want
to create a non-prefixed index, it must be created as LOCAL .
A standard index that is not partitioned and covers the entire table. There will be only one segment
for global non partitioned index.
Index created.
Global prefixed index is Creating index as per partition key column . A global prefixed index in
Oracle is a type of index that is global (not tied to specific partitions of a partitioned table) and is
defined with a leading column (or columns) that enhances query performance when filtering by that
column.
If you are creating global partition index on other column than partition key i.e Global Non-Prefixed
Indexes , you will get error ORA-14038: GLOBAL partitioned index must be prefixed .But you can
create non-partitioned global prefixed index.
Index created.
Index created.
2. LOCAL INDEX
local indexes are inherently tied to the partitioning of the table ,it must be partitioned according to
the table's partitioning scheme. If you want a non-partitioned index, you should create a global non-
partitioned index instead.
Index created.
Local Non-Prefixed Indexes - (local indexes on other than partition key column)
Index created.
For example, suppose there is a primary key on TRANS, on the TRANS_ID column. The primary key
can be anywhere inside the table, across all the partitions. In this case, the index entries of a
partition of the table may exist outside the corresponding partition of the index. For such a situation,
create a global index.
i) local indexes are easier to manage and oracle automatically manages the maintainance.
ii) Global indexes are not managed by oracle automatically, Means if we drop any partitions from
table global index will go unusable.In this case you need to rebuild them or you can drop partition
with clause update global indexes.
alter table table_name drop partition part1 update global indexes;
C.PARTITION PRUNING
Partition pruning ensure that queries can skip irrelevant partitions by filtering on partition keys. This
reduces the amount of data scanned.
o Static partition pruning: If the where condition has constant values. (Compile time)
o Dynamic partition pruning: If the where condition has some calculations, functions, etc.
(Run time)
To optimize queries with range partitions, use your partition key with these conditions:
CONDITIONS:-
Range Conditions: Use =, <, <=, >, >=, BETWEEN, or LIKE to compare the key with
literals or bind variables.
o Examples:
col = :my_date
col BETWEEN :my_date AND :my_date + 3
col = (SELECT processing_date FROM
current_processing_date)
Using functions on partition columns prevents partition pruning. This includes any
type conversions.
For example
WHERE TRUNC(my_column) BETWEEN SYSDATE - 30 AND SYSDATE
EXAMPLE:-
And inserted 4 records 1 record in each partition. After commiting performed stats gather.
Table created.
SQL>
SQL> insert into TRANSACTIONS1 values(1,'01-MAR-2023');
insert into TRANSACTIONS1 values(2,'01-JUN-2023');
insert into TRANSACTIONS1 values(3,'01-JUL-2023');
insert into TRANSACTIONS1 values(4,'01-DEC-2023');
1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL>
1 row created.
num_rows
FROM user_tab_partitions
WHERE table_name like 'TRANSACTIONS1%'
ORDER BY table_name, partition_name; 2 3 4 5 6
ii)Now we run a simple select statement and check for execution plan.Focus on the Pstart and Pstop
columns in the execution plan. Without a filter, all partitions are read. (partition range all)
If we add a WHERE condition using the partition key, the execution plan will change to read only the
relevant partitions. In some case If you see "KEY" in the Pstart and Pstop columns, it means the
query parser couldn't identify which partitions to access, but the optimizer expects partition pruning
to happen during execution. This often occurs when there’s an equality condition on the partition
key that involves a function.
Iii)Here Using functions in the WHERE clause cancels partition pruning, causing the database to read
all partitions. if TRANSACTION_DATE is already a date type, converting it to a date again might lead
to performance issues because it forces a conversion for every row and cancels partition pruning .
Hence you should avoid using functions on colums.You can use the functions on literals.
Below query directly compares the TRANSACTION_DATE column without any function applied.
This is more efficient, especially if TRANSACTION_DATE is already in a date format. It allows for
better performance and can leverage partition pruning if applicable.
EXTRAS:-
1.OUTPUT RATIO:-
Consider you have table with 10M rows that has been partitioned into four partitions then,
i) If your query is fetching less than or equal to 10 to 15 % rows ,then it should go for index scan if
there is filter condition as per indexed column.
ii) If your query is fetching more than 15 to 70 % rows ,then it should go for partition pruning.
iii) If your query is fetching more than 70% rows then it should be full table scan.(check for
db_file_multiblock_read parameter).
Cardinality: Prefer columns with a high cardinality (many distinct values) to ensure even distribution
of data across partitions.
Skewed Data: Avoid columns with skewed distributions that might lead to uneven partition sizes,
which can affect performance.
Historical Data Management: Use columns that reflect the data's lifecycle, such as dates (e.g.,
order_date), which can help with archiving and purging old data.
Time-Based Queries: If data is often queried based on time periods (e.g., monthly or yearly),
consider date columns for range partitioning.
3. VIEWS
DBA_PART_TABLES
DBA_TAB_PARTITIONS
DBA_TAB_SUBPARTITIONS
DBA_PART_KEY_COLUMNS
DBA_SUBPART_KEY_COLUMNS
DBA_PART_COL_STATISTICS
DBA_SUBPART_COL_STATISTICS
DBA_PART_HISTOGRAMS
DBA_SUBPART_HISTOGRAMS
DBA_PART_INDEXES
DBA_IND_PARTITIONS
DBA_IND_SUBPARTITIONS
4. INTERVAL IN PARTITION
1) NUMTOYMINTERVAL
2) NUMTODSINTERVAL
Use: Useful for creating partitions based on days or smaller time intervals.
If row movement is not enabled, changes that would require a row to be moved to another partition
might result in errors. Please check below example for ref(table is range partition).
i) Modifying partitioning strategies, such as splitting or merging partitions, can also affect ROWIDs as
rows may need to be relocated.
ii) Also if we are changing partition key .
iii) If you perform update column(partitioned key column) that requires a row to be moved , you
need to enable row movement else you will end with below error.
Table altered.
1 row updated.
SQL>
REFERENCES;
1. Oracle Documentation
2. Hemant Oracle DBA Blog
3. OraFAQ Partition Pruning