Está en la página 1de 224

Oracle8i Concepts

Release 8.1.5
A67781-01

11
Partitioned Tables and Indexes
Like to a double cherry, seeming parted,
But yet an union in partition;
Two lovely berries molded on one stem.
Wm. Shakespeare: A Midsummer-Night's Dream
This chapter describes partitioned tables and indexes, and explains some
administrative considerations for partitioning. It covers the following topics:
Introduction to Partitioning
Basic Partitioning Model
Rules for Partitioning Tables and Indexes
DML Partition Locks and Subpartition Locks
Maintenance Operations
Managing Indexes
Privileges for Partitioned Tables and Indexes
Auditing for Partitioned Tables and Indexes
Partition-Extended and Subpartition-Extended Table Names

Attention:
The features described in this chapter are available only if you have
purchased Oracle8i Enterprise Edition with the Partitioning Option.
See Getting to Know Oracle8i for information about the features and options
available with Oracle8i Enterprise Edition.

Introduction to Partitioning
This section explains how partitioning can help you manage large tables and indexes
in an Oracle database. It includes the following sections:
What Is Partitioning?
Advantages of Partitioning
Manual Partitioning with Partition Views
Note:
Oracle supports partitioning only for tables, indexes on tables, materialized
views, and indexes on materialized views; Oracle does not support
partitioning of clustered tables or indexes on clustered tables.

Additional Information:
See Oracle8i Tuning for information about partitioning materialized views.

What Is Partitioning?
Partitioning addresses the key problem of supporting very large tables and indexes by
allowing you to decompose them into smaller and more manageable pieces
called partitions. Once partitions are defined, SQL statements can access and
manipulate the partitions rather than entire tables or indexes. Partitions are especially
useful in data warehouse applications, which commonly store and analyze large
amounts of historical data.
Partitioning Methods

Two primary methods of partitioning are available: range partitioning, which


partitions the data in a table or index according to a range of values, and hash
partitioning, which partitions the data according to a hash function. Another
method, composite partitioning, partitions the data by range and further subdivides the
data into subpartitions using a hash function. See "Basic Partitioning Model" for more
information about these partitioning methods.
Logical and Physical Attributes

All partitions of a table or index have the same logical attributes, although their
physical attributes may be different. For example, all partitions in a table share the
same column and constraint definitions, and all partitions in an index share the same
index columns, but storage specifications and other physical attributes such as
PCTFREE, PCTUSED, INITRANS, and MAXTRANS may vary for different
partitions of the same table or index.
Like partitions, all subpartitions of a table or index have the same logical attributes.
Unlike partitions, however, the subpartitions of a single partition cannot have different
physical attributes.
Storage of Partitions and Subpartitions

A separate segment stores each partition of a range-partitioned or hash-partitioned


table or index, and each subpartition of a composite-partitioned table or index. The
partitions of a composite-partitioned table or index are logical structures only--they do
not occupy separate segments because their data is stored in the segments of their
subpartitions.
Optionally, you can store each partition (or subpartition of a composite-partitioned
table or index) in a separate tablespace, which has the following advantages:
You can contain the impact of data corruption.

You can back up and recover each partition (or subpartition) independently.
You can map partitions (or subpartitions) to disk drives to balance the I/O load.
Example of a Partitioned Table

In Figure 11-1, the SALES table contains historical data divided by week number into
13 four-week partitions.
Figure 11-1 SALES Table Partitioned by Week

This SQL statement creates the range-partitioned table shown in Figure 11-1:
CREATE TABLE sales ( acct_no

NUMBER(5),
acct_name
CHAR(30),
amount_of_sale
NUMBER(6),
week_no
INTEGER )
PARTITION BY RANGE ( week_no ) ...
(PARTITION sales1 VALUES LESS THAN ( 4 ) TABLESPACE ts0,
PARTITION sales2 VALUES LESS THAN ( 8 ) TABLESPACE

ts1,

...
PARTITION sales13 VALUES LESS THAN ( 52 ) TABLESPACE

ts12 );

Additional Information:
For more examples of partitioned tables, see the Oracle8i Administrator's
Guide.

Partition Pruning

The Oracle server incorporates the intelligence to explicitly recognize partitions and
subpartitions. This knowledge is exploited in optimizing SQL statements to mark the
partitions or subpartitions that need to be accessed,
eliminating ("pruning") unnecessary partitions or subpartitions from access by those
SQL statements.

For each SQL statement, depending on the selection criteria specified, unneeded
partitions or subpartitions can be eliminated. For example, if a query only involves Q1
sales data, there is no need to retrieve data for the remaining three quarters. Such
intelligent pruning can dramatically reduce the data volume, resulting in substantial
improvements in query performance.
If the optimizer determines that the selection criteria used for pruning are satisfied by
all the rows in the accessed partition or subpartition, it removes those criteria from the
predicate list (WHERE clause) during evaluation in order to improve performance.
However, the optimizer cannot prune partitions if the SQL statement applies a
function to the partitioning column, with the exception of the TO_DATE function.
(Similarly, the optimizer cannot use an index if the SQL statement applies a function
to the indexed column, unless it is a function-based index.) See "DATE Datatypes".
Pruning can eliminate index partitions even when the underlying table's partitions
cannot be eliminated, if the index and table are partitioned on different columns. You
can often improve the performance of operations on large tables by creating
partitioned indexes which reduce the amount of data that your SQL statements need to
access or modify.
The ability to prune unneeded partitions or subpartitions from SQL statements
increases performance and availability for many purposes, including partition-level or
subpartition-level load, purge, backup, restore, reorganization, and index building.
Partition-Wise Joins

An additional area of optimization for partitioned tables is a partition-wise join, which


is a large join operation that is broken into smaller joins that are performed
sequentially or in parallel.
In order to use partition-wise joining, both tables must be equipartitioned
(see "Equipartitioning").
If the optimizer determines that partition-wise joining provides a performance gain,
then it will be used. In some situations, the optimizer can combine pruning and
partition-wise joining.
Additional Information:
For detailed information about partition-wise joins, see Oracle8i Tuning.

Advantages of Partitioning
This section identifies the classes of databases that could benefit from the use of
partitioning, and characterizes them in terms of the problems they present:
Very Large Databases (VLDBs)
Reducing Downtime for Scheduled Maintenance
Reducing Downtime Due to Data Failures
DSS Performance
I/O Performance
Disk Striping: Performance versus Availability
Partition Transparency
Very Large Databases (VLDBs)

A Very Large Database (VLDB) contains hundreds of gigabytes or even a few


terabytes of data. Partitioning provides support for VLDBs that contain mostly
structured data, rather than unstructured data. These VLDBs typically owe their size
to the presence of a few very large data objects (tables and indexes) rather than to the
presence of a very large number of data objects.
There are two major categories of VLDB:
On-Line Transaction Processing (OLTP) databases are designed for large
numbers of concurrent transactions, where each transaction is a relatively
simple operation processing a small amount of data.
Decision Support Systems (DSS) are designed for very complex queries that
need to access and process large amounts of data.

A VLDB can be characterized as an OLTP database if most of its workload is OLTP.


Similarly, a VLDB can be characterized as a DSS database if most of its workload
consists of DSS queries.
Partitioning efficiently supports both OLTP VLDBs and DSS VLDBs.
Historical Databases

Historical databases are the most common type of DSS VLDB. They contain two
classes of tables: historical tables and enterprise tables.
Historical tables describe the business transactions of an enterprise over a
recent time interval, such as the last 24 months. There are two types of
historical tables:
o Base tables contain the baseline information (for example, sales, checks,
and orders).
o Rollup tables contain summary information derived from the base
information using operations such as GROUP BY, AVERAGE, and
COUNT.
The time interval reflected in a historical table is a rolling window, so
periodically the database administrator (DBA) deletes the set of rows
describing the oldest transactions and allocates space for the set of rows
describing new transactions. For example, at the close of business on April 30,
1997 the DBA deletes the rows (and all supporting index entries) that describe
May 1995 transactions and allocates space for May 1997 transactions.
The vast majority of data in a historical VLDB is stored in few very large
historical tables that present special problems due to their size and the
requirement to smoothly roll out old data and roll in new data.
Enterprise tables describe the business entities of the enterprise (for example,
departments, locations, and products). This information changes slowly over
time and is not modified on a periodic schedule. Although enterprise tables are
not large, they affect the performance of many long-running DSS queries that
consist of joins of a historical table with enterprise tables.
Partitioning addresses the problem of supporting large historical tables and their
indexes by dividing historical data into time-related partitions that can be managed
independently and added or deleted conveniently.

Mission-Critical Databases

Mission-critical OLTP databases present special availability and performance


problems even if they are not very large. For example, it may be necessary to perform
scheduled maintenance operations or recover a 10-gigabyte table in a very short
period of time, perhaps an hour or less. Also, the DBA may need a degree of control
over data placement that is hard to achieve when a table or index is spread over
multiple drives.
Partitioning can increase the availability of mission-critical databases if critical tables
and indexes are divided into partitions to reduce the maintenance windows, recovery
times, and impact of failures. You can also improve access performance to a critical
table or index by controlling performance parameters on a partition basis.
Reducing Downtime for Scheduled Maintenance

Partitions enable data management operations like data loads, index creation, and data
purges at the partition level, rather than on the entire table, resulting in significantly
reduced times for these operations.
Partitioning can significantly reduce the impact of scheduled downtime for
maintenance operations:
By introducing partition maintenance operations that operate on an individual
partition rather than on an entire table or index.
By providing partition independence so that maintenance operations can be
performed concurrently on different partitions.
Note:
Composite-partitioned tables and indexes have subpartition maintenance
operations as well as partition maintenance operations, and subpartition
independence as well as partition independence. In the discussion that
follows, the general term "partition" refers to both partitions and
subpartitions.

Partition Maintenance Operations

Partition maintenance operations are faster than full table or index maintenance
operations. A speedup can be achieved equal to the ratio:
(# records in full table or index) / (# records in partition)
provided there are no interpartition stored constructs (global indexes and referential
integrity constraints).
To further reduce downtime, a partition maintenance operation can take advantage of
performance features that are available for table and index-level maintenance
operations, such as the PARALLEL, NOLOGGING, and DIRECT (or APPEND)
options where applicable.
Partition Independence

Partition independence for the partition maintenance operations makes it possible to


perform concurrent maintenance operations on different partitions of the same table or
index, as well as concurrent SELECT and DML operations against partitions that are
unaffected by maintenance operations.
For example, you can Direct Path Load into partitions PA and PB at the same time,
while applications are executing standard SQL SELECT and DML operations against
other partitions.
Partition independence is particularly important for operations that involve data
movement. Such operations can take a long time (minutes, hours, or even days).
Partitioning can reduce the window of unavailability on other partitions to a short time
(few seconds) during operations that involve data movement, provided there are no
inter-partition stored constructs (global indexes and referential integrity constraints).
Partition independence is not needed for short operations (no data movement) because
these operations complete in a short time.
Reducing Downtime Due to Data Failures

Some maintenance operations are unplanned events, required to recover from


hardware or software failures that cause data loss or corruption. Recovery from
hardware failures and many system software failures is accomplished by running the
RECOVER command on a database, tablespace, or datafile. Any tables or indexes that
have records in a tablespace or datafile being recovered remain unavailable during
recovery. Increased availability is particularly important for mission-critical OLTP
databases.

Because partitions are independent of each other, the unavailability of a piece (or a
subset of pieces) does not affect access to the rest of the data.
Storing partitions in separate tablespaces provides the following benefits:
Downtime due to execution of the RECOVER command is reduced because the
unit of recovery (a tablespace) is smaller.
Disk resources needed for recovery of an offline tablespace (deferred rollback
segments) are reduced because the unit of recovery is smaller.
The amount of unavailable data is reduced, because only the partition(s) stored
in the recovered tablespace have to be taken offline. User applications and
maintenance operations can still access the other partitions. This is another
example of partition independence.
DSS Performance

DSS queries on very large tables present special performance problems. An ad-hoc
query that requires a table scan can take a long time, because it must inspect every
row in the table; there is no way to identify and skip subsets of irrelevant rows. The
problem is particularly important for historical tables, for which many queries
concentrate access on rows that were generated recently.
Partitions help solve this DSS performance problem. An ad-hoc query which only
requires rows that correspond to a single partition (or range of partitions) can be
executed using a partition scan rather than a table scan.
For example, a query that requests data generated in the month of October 1997 can
scan just the rows stored in the October 1997 partition, rather than rows generated
over many years of activity. This improves response time and it can also substantially
reduce the temporary disk space requirement for queries that require sorts.
I/O Performance

Partitioning can control how data is spread across physical devices. To balance I/O
utilization, you can specify where to store the partitions of a table or index.
With this level of location control, you can accommodate the special needs of
applications that require fast response time by reducing disk contention and using
faster devices. On the other hand, data that is accessed infrequently, such as old

historical data, can be moved to slow disks or stored in subsystems that support a
storage hierarchy.
Disk Striping: Performance versus Availability

Disk striping and partitioning are both tools that can improve performance through the
reduction of contention for disk arms. Which tool to use, or in which proportions to
use them together, is an important issue to consider when physically designing
databases. These issues should be considered not only with respect to performance,
but also with respect to availability and partition independence.
Figure 11-2 shows the two extremes of combining partitioning and striping. Both (a)
and (b) in Figure 11-2 show four partitions spread across eight disks, but (a) stripes
each partition onto its own pair of disks, whereas (b) stripes each partition onto all
eight disks.
The performance characteristics are better in (b), but if any single disk failure
occurs, all partitions are adversely affected.
The availability characteristics are better in (a), because failure of a single disk
only affects one partition.
Intermediate configurations are also possible, where subsets of partitions are striped
over subsets of disks.
Figure 11-2 Partitions and Disk Striping

The trade-off between performance and availability must be decided when


determining how to partition tables and indexes, and how to stripe the disks on which
they are stored.
For mission-critical databases it is recommended that partition independence and
availability be favored, therefore each partition that you want to stripe across disks
should be striped onto its own set of disk drives, which should include enough drives
to achieve the required I/O parallelism for accesses to that partition.
Partition Transparency

The vast majority of application programs require partition transparency, that is the
programs should be insensitive to whether the data they access is partitioned and how
it is partitioned.
A few application programs, however, can take advantage of partitions by explicitly
requesting access to an individual partition, rather than the entire table. For example, a
user might want to break a long batch job on a very large table into a sequence of
short nightly batch jobs on individual partitions.
Manual Partitioning with Partition Views
Instead of using partitioned tables, you can build separate tables with identical
templates and define a view that does a UNION of these tables. This is known
as manual partitioning, and the view is known as a partition view. Partition views
were the only form of partitioning available in Oracle7 Release 7.3. They are not
recommended for new applications in Oracle8i.
Note:
Oracle8i supports partition views solely for backwards compatibility with
Oracle7 Release 7.3. Future releases of Oracle will not support partition
views, starting with Oracle Release 9.

Partition views that were created for Oracle7 databases can be converted to partitioned
tables by using the EXCHANGE PARTITION option of the ALTER TABLE
command.
Additional Information:
See the Oracle8i Administrator's Guide for instructions on converting
partition views to partitioned tables.

The basic idea behind partition views is to divide a large table into multiple physical
tables using a WHERE clause or CHECK constraint as a partitioning criterion, then
glue the smaller tables together into a whole with a UNION ALL view. You can then
define sets of "base indexes" with identical key specifications on the base tables,
which provide indexing capabilities when the UNION ALL view is used. (Partition
views must be indexed to work properly.) Compared to nonpartitioned tables, partition
views should not add significant CPU overhead. Queries that use a key range to select
from a partition view access only the base tables that lie within the key range. The
optimizer can use separate execution plans for a partition view's base tables. (In
contrast, the optimizer uses a single execution plan for all partitions in a partitioned
table.)
Disadvantages of Partition Views

Manual partitioning with partition views has many disadvantages in comparison with
partitioned tables:
Configuration complexity
The database administrator is responsible for correctly defining the base tables
and indexes that correspond to partitions, and for maintaining these definitions.
The equivalent of DDL operations that move data across partitions (split, move,
and so on) must be implemented via Export/Import or SQL scripts.
Lack of partition transparency
Some SQL operations must be performed using the base tables rather than the
UNION ALL view. For example, INSERT refers to a base table, and user code
is needed to obtain the table name that appears in an INSERT statement.
Lack of performance
Some SQL operations on the UNION ALL view may perform badly because
the optimizer does not take advantage of all the existing base indexes.
Poor memory utilization
A SQL compiled query operating on a UNION ALL view internally replicates
descriptive information for all tables that support the view.
DDL restrictions

Global indexes and referential integrity constraints cannot be defined on the


UNION ALL view.
Load restrictions
It is not possible to perform direct loads on a UNION ALL view.
Guidelines for Partition Views

To create and maintain partition views, follow the guidelines in Table 11-1.

Table 11-1 Partition View Guidelines

To use partition views, the PARTITION_VIEW_ENABLED parameter must be set.

DDL commands must be issued separately for each underlying table. For example, to add an
index to a partition view, you must add indexes to all underlying tables. To analyze a partition
view, you must analyze all underlying tables. However, you can submit operations on each
partition in parallel.

Administrative operations must be performed as operations on the underlying tables of the


partition view, not on the partition view itself. For example, a split operation consists of either
one or two CREATE TABLE AS SELECT operations (one if the split is "in place"), followed
by a redefining of the partition view's view text.

You can create referential integrity constraints on underlying tables, but for the constraints to be
true for the partition view, the primary key must contain the partition column.

Similarly, you can have an unique index on underlying tables, but for uniqueness to be true for
the partition view, the partition column must be contained in the unique index. (You can have
only one unique index.)

Every partition has its own index, so any index lookup must be done in all indexes for partitions

that are not skipped.

A partition view cannot be the target of a DML statement (UPDATE, INSERT, or DELETE).

Partition views do not support concatenated partitioning keys.

SQL*Loader does not support partition views.

Basic Partitioning Model


This section describes the basic partitioning model, which includes these partitioning
methods:
Range Partitioning
Hash Partitioning
Composite Partitioning
and these additional topics:
Partition and Subpartition Names
Partitioning and Subpartitioning Columns and Keys
Partition Bounds for Range Partitioning
Equipartitioning
You can partition a table or index with options to the CREATE TABLE or CREATE
INDEX statement. After creating a partitioned table or index, you can use an ALTER
TABLE or ALTER INDEX statement to modify its partitioning attributes.

The partitioning syntax for CREATE TABLE and CREATE INDEX statements is very
similar. The CREATE TABLE statement specifies:
1 The logical attributes of the table, such as column and constraint definitions.
1 The physical attributes of the table.
o If the table is nonpartitioned, these are the real physical attributes of the
segment associated with the table.
o If the table is partitioned, these table-level attributes specify defaults for
the individual partitions of the table.
1 For a partitioned table, there is also a partition specification that includes:
o the table-level algorithm used to map rows to partitions
o a list of partition descriptions, one for each partition in the table
o a list of subpartition descriptions (only for composite partitioning).
Each partition description includes a clause defining supplemental partitionlevel information about the algorithm used to map rows to partitions. This
clause can also specify a partition name and physical attributes for the partition.
Each subpartition description (for composite partitioning) can specify a
subpartition name and a tablespace for the subpartition.
Datatype Restrictions

Partitioned tables cannot have any columns with LONG or LONG RAW datatypes. If
a table or index is partitioned on a column that has the DATE datatype and if the NLS
date format does not specify the century with the year, the partition descriptions must
use the TO_DATE function to specify the year completely; otherwise you cannot
create the table or index.
See "DATE Datatypes" for examples.
Bitmap Restrictions

You can create bitmap indexes on partitioned tables, with the restriction that the
bitmap indexes must be local to the partitioned table--they cannot be global indexes.
(See "Index Partitioning".)

Cost Based Optimization

Cost based optimization is used when a SQL statement accesses partitioned tables or
indexes; rule base optimization is not available for partitions. A single execution plan
is used for all partitions of a partitioned table.
Statistics can be gathered by partition or subpartition, using the DBMS_STATS
package or the ANALYZE command. It is important to gather statistics whenever the
nature of the data in a partitioned table changes significantly. The statistics can be
found in these data dictionary views:

ALL_TAB_PARTITIONS, DBA_TAB_PARTITIONS, USER_TAB_PARTITIONS

ALL_TAB_SUBPARTITIONS, DBA_TAB_SUBPARTITIONS,
USER_TAB_SUBPARTITIONS

ALL_IND_PARTITIONS, DBA_IND_PARTITIONS, USER_IND_PARTITIONS

ALL_IND_SUBPARTITIONS, DBA_IND_SUBPARTITIONS, USER_IND_SUBPARTITIONS

ALL_PART_COL_STATISTICS, DBA_PART_COL_STATISTICS,
USER_PART_COL_STATISTICS

ALL_SUBPART_COL_STATISTICS, DBA_SUBPART_COL_STATISTICS,
USER_SUBPART_COL_STATISTICS

Range Partitioning
Range partitioning maps rows to partitions based on ranges of column values. Range
partitioning is defined by the partitioning specification for a table or index:
PARTITION BY RANGE ( column_list )

and by the partitioning specifications for each individual partition:


VALUES LESS THAN ( value_list )

where:
column_list is an ordered list of columns that determines the partition to which
a row or an index entry belongs.
o These columns are called the partitioning columns.
o The values in the partitioning columns of a particular row constitute that
row's partitioning key.
value_list is an ordered list of values for the columns in column_list.
o Each value in value_list must be either a literal or a TO_DATE() or
RPAD() function with constant arguments. (See "DATE Datatypes".)
o The value_list contained in the partitioning specification for each
partition defines an open (noninclusive) upper bound for the partition,
referred to as the partition bound.
o The partition bound for each partition must compare less than the
partition bound for the next partition.
In each partition, all rows (or rows pointed to by index entries) have partitioning
keys that compare less than the partition bound for that partition. Unless the partition
is the first partition in the table or index, all of its partitioning keys also compare
greater than or equal to the partition bound for the previous partition. See "Partition
Bounds for Range Partitioning" for more information about how partitioning keys are
compared to partition bounds, including how multicolumn partitioning keys are
handled.
For example, in the following table of four partitions (one for each quarter's sales), a
row with SALE_YEAR=1997, SALE_MONTH=7, and SALE_DAY=18 has
partitioning key (1997, 7, 18); therefore it belongs in the third partition and would be
stored in tablespace TSC. A row with SALE_YEAR=1997, SALE_MONTH=7, and
SALE_DAY=1 has partitioning key (1997, 7, 1) and also belongs in the third
partition, stored in tablespace TSC.

CREATE TABLE sales


( invoice_no NUMBER,
sale_year INT NOT NULL,
sale_month INT NOT NULL,
sale_day
INT NOT NULL )
PARTITION BY RANGE (sale_year, sale_month, sale_day)
( PARTITION sales_q1 VALUES LESS THAN (1997, 04, 01)
TABLESPACE tsa,
PARTITION sales_q2 VALUES LESS THAN (1997, 07, 01)
TABLESPACE tsb,
PARTITION sales_q3 VALUES LESS THAN (1997, 10, 01)
TABLESPACE tsc,
PARTITION sales_q4 VALUES LESS THAN (1998, 01, 01)
TABLESPACE tsd );

You can use the ALTER TABLE MERGE PARTITIONS command to merge the
contents of two adjacent range partitions into one partition. You might want to do this
to keep historical data online in larger partitions. For example, you might want to have
daily partitions, with the oldest partition rolled up into weekly partitions, which can
then be rolled up into monthly partitions, and so on.
Hash Partitioning
Although partitioning by range is well-suited for historical databases, it may not be
the best choice for other purposes. Another method of partitioning, hash partitioning,
uses a hash function on the partitioning columns to stripe data into partitions. Hash
partitioning allows data that does not lend itself to range partitioning to be easily
partitioned for performance reasons (such as parallel DML, partition pruning, and
partition-wise joins).
Hash partitioning is a better choice than range partitioning when:
you do not know beforehand how much data will map into a given range
sizes of range partitions would differ quite substantially
partition pruning and partition-wise joins on a partitioning key are important
(see "Partition Pruning" and "Partition-Wise Joins")
The number of partitions should be a power of two (2, 4, 8, and so on) to obtain the
most even data distribution. Hash partitions can be named and stored in specific
tablespaces. Local indexes on hash partitions are equipartitioned with the table data.
For local index partitions, you can specify the partition names and tablespaces.

The following example creates a table that names and stores a hash partition in a
specific tablespace:
CREATE TABLE product( ... )
STORAGE (INITIAL 10M)
PARTITION BY HASH(column_list)
( PARTITION p1 TABLESPACE h1,
PARTITION p2 TABLESPACE h2 );

The concepts of splitting, dropping, and merging partitions do not apply to hash
partitions. However, you can increase or decrease the number of partitions by using
ALTER TABLE to ADD or COALESCE hash partitions.
Composite Partitioning
Composite partitioning partitions data using the range method and, within each
partition, subpartitions it using the hash method. This type of partitioning supports
historical operations data at the partition level and parallelism (parallel DML) and
data placement at the subpartition level.
Composite partitioning:
Provides ease-of-management advantages of range partitioning.
Provides data placement and parallelism advantages of hash partitioning.
Allows you to name the subpartitions and store them in specific tablespaces.
Allows you to build local indexes on composite-partitioned tables, which are
stored in the same tablespace as the table subpartition by default.
Allows you to build range-partitioned global indexes.
Allows you to name the index subpartitions and specify their tablespaces.
The partitions of a composite-partitioned table or index are logical structures only-their data is stored in the segments of their subpartitions.
The following example creates a table that uses composite partitioning (assuming the
NLS DATE format is DD-MON-YYYY):
CREATE TABLE orders(
ordid NUMBER,

orderdate DATE,
productid NUMBER,
quantity NUMBER)
PARTITION BY RANGE(orderdate)
SUBPARTITION BY HASH(productid) SUBPARTITIONS 8
STORE IN(ts1,ts2,ts3,ts4,ts5,ts6,ts7,ts8)
( PARTITION q1 VALUES LESS THAN('01-APR-1998'),
PARTITION q2 VALUES LESS THAN('01-JUL-1998'),
PARTITION q3 VALUES LESS THAN('01-OCT-1998'),
PARTITION q4 VALUES LESS THAN(MAXVALUE));

In this example, the ORDERS table is range partitioned on the ORDERDATE key, in
four separate ranges representing quarters of the year. Each range partition is further
subpartitioned on the PRODUCTID key into eight subpartitions, for a total of 32
subpartitions. Each tablespace contains one subpartition from each partition.
The following example creates a table that uses composite partitioning with each
subpartition explicitly named and stored in a specified tablespace:
CREATE TABLE orders( ... )
PARTITION BY RANGE(orderdate)
SUBPARTITION BY HASH(productid) SUBPARTITIONS 8
STORE IN (ts1,ts2,ts3,ts4,ts5,ts6,ts7,ts8)
( PARTITION q1 VALUES LESS THAN('01-APR-1998')
( SUBPARTITION q1_h1 TABLESPACE ts1,
...
SUBPARTITION q1_h7 TABLESPACE ts7,
SUBPARTITION q1_h8 TABLESPACE ts8)
PARTITION q2 VALUES LESS THAN('01-JUL-1998'), ... );

Partition and Subpartition Names


Every partition or subpartition has a name, which must conform to the usual rules for
naming schema objects and their parts. In particular:
The name of a table partition or subpartition must be unique among all the
partitions or subpartition belonging to the same parent table.
The name of an index partition or subpartition must be unique among all the
partitions or subpartition belonging to the same parent index.
For composite partitioning, the names of subpartitions and partitions are in the same
namespace; that is, a partition and a subpartition belonging to the same parent table or
index cannot have the same name.
You can rename a partition or subpartition; however, you cannot create any synonyms
on a partition or subpartition name.

Additional Information:
See Oracle8i SQL Reference for more information about the rules for naming
schema objects.

Referencing a Partition or Subpartition

Partition and subpartition names can optionally be referenced in DDL and DML
statements and in utility statements like Import/Export and SQL*Loader. They always
appear in context with the name of their parent table or index and they are never
qualified by a schema name. (The schema name can be used to qualify the parent table
or index.) For example:
ALTER TABLE admin.patient_visits DROP PARTITION pv_dec92;
SELECT * FROM sales PARTITION (s_nov97) s WHERE s.amount_of_sale > 1000;

See "Partition-Extended and Subpartition-Extended Table Names" for more


information about referencing partitions and subpartitions in SQL statements.
Partitioning and Subpartitioning Columns and Keys
The partitioning columns (or subpartitioning columns) of a table or index consist of
an ordered list of columns whose values determine how the data is partitioned (or
subpartitioned). This list can include up to 16 columns, and cannot include any of the
following types of columns:
a LEVEL or ROWID pseudocolumn
a column of the ROWID datatype
a nested table, VARRAY, object type, or REF column
a LOB column (BLOB, CLOB, NCLOB, or BFILE datatype)
A row's partitioning key is an ordered list of its values for the partitioning columns.
Similarly, in composite partitioning a row's subpartitioning key is an ordered list of its
values for the subpartitioning columns. Oracle applies either the range or hash method

to each row's partitioning key (or subpartitioning key) to determine which partition (or
subpartition) the row belongs in.
Partition Bounds for Range Partitioning
In a range-partitioned table or index, the partitioning key of each row is compared
with a set of upper and lower bounds to determine which partition the row belongs in.
(See "Range Partitioning" for a general description of range partitioning.)
Every partition of a range-partitioned table or index has a noninclusive upper
bound, which is specified by the VALUES LESS THAN clause.
Every partition except the first partition also has an inclusive lower bound,
which is specified by the VALUES LESS THAN on the next-lower partition.
The partition bounds collectively define an ordering of the partitions in a table or
index. The "first" partition is the partition with the lowest VALUES LESS THAN
clause, and the "last" or "highest" partition is the partition with the highest VALUES
LESS THAN clause.
Comparing Partitioning Keys with Partition Bounds

If you attempt to insert a row into a table and the row's partitioning key is greater than
or equal to the partition bound for the highest partition in the table, the insert will fail.
When comparing character values in partitioning keys and partition bounds,
characters are compared according to their binary values. However, if a character
consists of more than one byte, Oracle compares the binary value of each byte, not of
the character. The comparison also uses the comparison rules associated with the
column data type (for example, blank-padded comparison is done for the ANSI
CHAR data type). The NLS parameters, specifically the initialization parameters
NLS_SORT and NLS_LANGUAGE and the environment variable NLS_LANG, have
no effect on the comparison.
See "Multicolumn Partitioning Keys" for more information about comparing
partitioning keys.
MAXVALUE

You can specify the keyword MAXVALUE for any value in the partition
bound value_list. This keyword represents a virtual "infinite" value that sorts higher
than any other value for the data type, including the NULL value.

For example, you might partition the OFFICE table on STATE (a CHAR(10) column)
into three partitions with the following partition bounds:
VALUES LESS THAN ( 'I' ): States whose names start with A through H.
VALUES LESS THAN ( 'S' ): States whose names start with I through R.
VALUES LESS THAN ( MAXVALUE ): States whose names start with S
through Z, plus special codes for non-U.S. regions.
Nulls

NULL cannot be specified as a value in a partition bound value_list. An empty string


also cannot be specified as a value in a partition bound value_list, because it is treated
as NULL within the database server.
For the purpose of assigning rows to partitions, Oracle sorts nulls greater than all
other values except MAXVALUE. Nulls sort less than MAXVALUE.
This means that if a table is partitioned on a nullable column, and the column is to
contain nulls, then the highest partition should have a partition bound of
MAXVALUE for that column. Otherwise the rows that contain nulls will map above
the highest partition in the table and the insert will fail.
DATE Datatypes

If the partition key includes a column that has the DATE datatype and the NLS date
format does not specify the century with the year, you must specify partition bounds
using the TO_DATE() function with a 4-character format mask for the year; otherwise
you will not be able to create the table or index.
For example, you might create the SALES table using a DATE column:
CREATE TABLE sales
( invoice_no NUMBER,
sale_date DATE NOT NULL )
PARTITION BY RANGE (sale_date)
( PARTITION sales_q1
VALUES LESS THAN (TO_DATE('1997-04-01','YYYY-MM-DD'))
TABLESPACE tsa,
PARTITION sales_q2
VALUES LESS THAN (TO_DATE('1997-07-01','YYYY-MM-DD'))
TABLESPACE tsb,
PARTITION sales_q3
VALUES LESS THAN (TO_DATE('1997-10-01','YYYY-MM-DD'))
TABLESPACE tsc,

PARTITION sales_q4
VALUES LESS THAN (TO_DATE('1998-01-01','YYYY-MM-DD'))
TABLESPACE tsd );

When you query or modify data, it is recommended that you use the TO_DATE()
function in the WHERE clause so that the value of the date information can be
determined at compile time. However, the optimizer can prune partitions using a
selection criterion on partitioning columns of type DATE when you use another
format, as in the following examples:
SELECT * FROM sales
WHERE s_saledate BETWEEN TO_DATE('01-JUL-94', 'DD-MON-YY')
AND TO_DATE('01-OCT-94', 'DD-MON-YY');
SELECT * FROM sales
WHERE s_saledate BETWEEN '01-JUL-1994' AND '01-OCT-1994';

In this case, the date value will be complete only at runtime. Therefore you will not be
able to see which partitions Oracle is accessing as is usually shown on the
partition_start and partition_stop columns of the EXPLAIN PLAN command output
on the SQL statement. Instead, you will see the keyword 'KEY' for both columns.
Multicolumn Partitioning Keys

When a table or index is partitioned by range on multiple columns, each partition


bound and partitioning key is a list (or vector) of values. The partition bounds and
keys are ordered according to ANSI SQL2 vector comparison rules. (This is also the
way Oracle orders multicolumn index keys.)
To compare a partitioning key with a partition bound, you compare the values of their
corresponding columns until you find an unequal pair and then that pair determines
which vector is greater. The values of any remaining columns have no effect on the
comparison.
In mathematical terms, for vectors V1 and V2 which contain the same number of
values, Vx[i] is the ith value in Vx. Assuming that V1[i] and V2[i] have compatible
datatypes:
V1 = V2 if and only if V1[i] = V2[i] for all i.
V1 < V2 if and only if V1[i] = V2[i] for all i < n and V1[n] < V2[n] for some n.
V1 > V2 if and only if V1[i] = V2[i] for all i < n and V1[n] > V2[n] for some n.

For example, if the partition bound for partition P is (7, 5, 10) and the partition bound
for the next lower partition is (6, 7, 3) then:
Key (6, 9, 11) belongs in partition P, because:
o key (6, x, x) is less than (7, x, x)
o key (6, 9, x) is greater than (6, 7, x)
Note that the value in the key's third column can be greater than the
corresponding value in the partition bound--(x, x, 11) vs. (x, x, 10) in this case-because the comparison does not consider values in the third column after
finding an inequality in the second column.
Key (7, 3, 15) belongs in partition P, because:
o key (7, 3, x) is less than (7, 5, x)
o key (7, x, x) is greater than (6, x, x)
Note that the value in the key's first column can be equal to the value in the first
column of the partition bound. The VALUES LESS THAN clause applies to the
columns collectively, not to individual columns.
Keys (6, 5, 0) and (7, 5, 11) belong in other partitions.
If MAXVALUE appears as an element of a partition bound value_list, then the values
of all the following elements are irrelevant. For example, a partition bound of (10,
MAXVALUE, 5) is equivalent to a partition bound of (10, MAXVALUE, 6) or to a
partition bound of (10, MAXVALUE, MAXVALUE).
Multicolumn partitioning keys are useful when the primary key for the table contains
multiple columns, but rows are not distributed evenly over the most significant
column in the key. For example, suppose that the SUPPLIER_PARTS table contains
information about which suppliers provide which parts, and the primary key for the
table is (SUPPNUM, PARTNUM). It is not sufficient to partition on SUPPNUM
because some suppliers might provide hundreds of thousands of parts, while others
provide only a few specialty parts. Instead, you can partition the table on (SUPPNUM,
PARTNUM).
Multicolumn partitioning keys are also useful when you represent a date as three
CHAR columns instead of a DATE column.

Implicit Constraints Imposed by Partition Bounds

If you specify a partition bound other than MAXVALUE for the highest partition in a
table, this imposes an implicit CHECK constraint on the table. This constraint is not
recorded in the data dictionary (but the partition bound itself is recorded).
Equipartitioning
Two tables or indexes are equipartitioned when:
They have the same partitioning method (range or hash), the same partitioning
columns, the same number of partitions, and, for range partitioning, the same
partition bounds.
If at least one table or index is composite partitioned, then the tables or indexes
are equipartitioned if they are equipartitioned on at least one partitioning
method (range or hash). In this case, they are equipartitioned on one dimension.
They do not have to be the same type of schema object; for example, a table and an
index can be equipartitioned.
Range Equipartitioning

If A and B are range-partitioned tables or indexes, where A[i] is the ith partition in A
and B[i] is the ith partition in B, then A and B are equipartitioned if all of the
following are true:
They have the same number of partitions N.
They have the same number of partitioning columns M.
For every 1 <= i <= N, A[i] and B[i] have the same partition bound.
If Apcol[i] is the ith partitioning column in A and Bpcol[i] is the ith partitioning
column in B, then the following must also be true:
For 1 <= i <= M, Apcol[i] and Bpcol[i] have the same data type, including
length, precision, and scale.
A[i] and B[i] may differ in their physical attributes; in particular they do not have to
reside in the same tablespace.

Equipartitioning is important to consider when designing the database.


It reduces the downtime and the amount of data that is unavailable during
partition maintenance operations and tablespace recovery operations. For
example, because a table and its local indexes are equipartitioned the effect of
splitting a partition is limited to one table partition and the corresponding index
partitions. If a table has an index that is not local, then splitting one partition of
the table makes it necessary to reorganize the entire index.
Equipartitioning enables partition-wise join.
It makes tablespace incomplete recovery (point-in-time recovery) on related
subsets of data easier. For example, you might equipartition a table and its
primary key index, or a parent table and a child table. You could then recover
corresponding partitions to a point in time.
Example of Equipartitioning

Figure 11-3 shows four logically related schema objects that are equipartitioned:
ACCOUNTS is a table with two partitions which is range-partitioned on
column ACCOUNT_NO. The first partition contains account numbers up to
1000. The second partition contains account numbers up to 2000.
ACCOUNTS_IX is an index on column ACCOUNT_NO in the ACCOUNTS
table. Like the table, the index is range-partitioned on ACCOUNT_NO into two
partitions, which have the same partition bounds as partitions of ACCOUNTS.
CHECKS is a table with two partitions which is range-partitioned on column
ACCT_NO. Its partitions have the same partition bounds as partitions of the
ACCOUNTS table. ACCT_NO is a foreign key that references
ACCOUNT_NO in ACCOUNTS.
CHECKS_IX is an index on columns (ACCT_NO, CHECK_NO) in CHECKS.
It is range-partitioned on ACCT_NO into two partitions, which have the same
partition bounds as partitions of ACCOUNTS.
The logical relationship between the four schema objects is shown on the left
in Figure 11-3; the physical partitioning is shown on the right. (Triangles represent
indexes and rectangles represent tables.)
Figure 11-3 Equipartitioned Tables and Indexes

Rules for Partitioning Tables and Indexes


This section describes the rules for creating partitioned tables and indexes and the
physical attributes of partitions.
Table Partitioning
The rules for partitioning tables are simple:
A table can be partitioned, provided that:
o It is not part of a cluster.
o It does not contain LONG or LONG RAW datatypes.
You can mix partitioned and nonpartitioned indexes with partitioned and
nonpartitioned tables:
o A partitioned table can have partitioned and/or nonpartitioned indexes.
o A nonpartitioned table can have partitioned and/or nonpartitioned
indexes. (Only global indexes can be created on nonpartitioned tables-see "Global Partitioned Indexes".)
Physical Attributes of Table Partitions

This section discusses the physical attributes of table partitions for range, hash, and
composite partitioning.
Range and Hash Partitioning

Default physical attributes are initially specified when the CREATE TABLE statement
creates a partitioned table. Since there is no segment corresponding to the partitioned
table itself, these attributes are only used in derivation of physical attributes of
member partitions. Default physical attributes can later be modified using ALTER
TABLE MODIFY DEFAULT ATTRIBUTES.
For hash partitioning, all partitions have the same physical characteristics and so the
only physical attribute you can specify for a partition is its tablespace.

Physical attributes of table partitions created by CREATE TABLE or ALTER TABLE


ADD PARTITION are determined as follows:
Whenever the value of a partition attribute is not specified, the values of the
physical attributes specified (explicitly or by default) for the corresponding
base table are used.
For hash partitioning, ALTER TABLE MOVE PARTITION can be used to move the
partition to a different tablespace. For range partitioning, this statement can move the
partition or modify its physical attributes. Resulting attributes are determined as
follows:
Whenever a new value is not specified, the values that existed before the
statement was issued are used.
For range partitioning, the physical attributes of table partitions created by ALTER
TABLE SPLIT PARTITION are determined as follows:
Whenever a new value is not specified, the values of physical attributes of the
partition being split are used. (This also applies to global index split--missing
attributes are inherited from the index partition being split.)
Physical attributes of all partitions of a table may be modified by ALTER TABLE, for
example, ALTER TABLE tablename NOLOGGING changes the logging mode of all
partitions of tablename to NOLOGGING.
See "Tablespace and Storage Attributes of LOB Data Partitions" for additional
information about the physical attributes of table partitions that contain LOB
datatypes.
Composite Partitioning

For composite partitioning, the partitions specify default physical attributes for the
subpartitions and the subpartitions are similar to hash partitions, in that the only
physical attribute you can specify explicitly for a subpartition is its tablespace.
The default physical attributes are initially specified when the CREATE TABLE
statement creates a composite partitioned table. Since there is no segment
corresponding to the partitions or to the table itself, these attributes are only used in
derivation of the attributes for member subpartitions. The default attributes can later
be modified using ALTER TABLE MODIFY DEFAULT ATTRIBUTES or ALTER
TABLE MODIFY DEFAULT ATTRIBUTES FOR PARTITION.

The physical attributes for subpartitions created by CREATE TABLE or ALTER


TABLE ADD PARTITION are determined as follows:
Whenever the tablespace is not specified explicitly for a subpartition, the
tablespace specified (explicitly or by default) for the corresponding partition is
used.
Whenever the values of physical attributes for the partition are not specified,
the attributes specified (explicitly or by default) for the corresponding base
table are used.
ALTER TABLE MOVE SUBPARTITION can be used to move a subpartition to a
different tablespace, but it does not change other physical attributes of the
subpartition. ALTER TABLE MODIFY PARTITION modifies the physical attributes
of all of that partition's existing subpartitions as well as the default physical attributes
of the partition itself. You can use the FOR PARTITION clause of ALTER TABLE
MODIFY PARTITION to avoid changing the attributes of existing subpartitions.
Attributes modified at the table level affect the defaults at all three levels: table,
partition, and subpartition.
See "Tablespace and Storage Attributes of LOB Data Partitions" for additional
information about the physical attributes of table subpartitions that contain LOB
datatypes.
Index Partitioning
The rules for partitioning indexes are similar to those for tables:
An index can be partitioned with these exceptions:
o The index is not a cluster index.
o The index is not defined on a clustered table.
o A bitmap index on a partitioned table must be a local index.
You can mix partitioned and nonpartitioned indexes with partitioned and
nonpartitioned tables:
o A partitioned table can have partitioned and/or nonpartitioned indexes.

o A nonpartitioned table can have partitioned and/or nonpartitioned B*tree indexes.


o Bitmap indexes on nonpartitioned tables cannot be partitioned.
However, partitioned indexes are more complicated than partitioned tables because
there are four types of partitioned indexes: local prefixed, local nonprefixed, global
prefixed, and global nonprefixed. These types are described below. Oracle supports
three of the four types (global nonprefixed indexes are not useful in real applications).
Local Partitioned Indexes

In a local index, all keys in a particular index partition refer only to rows stored in a
single underlying table partition. A local index is created by specifying the LOCAL
attribute.
Oracle constructs the local index so that it is equipartitioned with the underlying table.
Oracle partitions the index on the same columns as the underlying table, creates the
same number of partitions or subpartitions, and gives them the same partition bounds
as corresponding partitions of the underlying table.
Oracle also maintains the index partitioning automatically when partitions in the
underlying table are added, dropped, merged, or split, or when hash partitions or
subpartitions are added or coalesced. This ensures that the index remains
equipartitioned with the table.
A local index can be created UNIQUE if the partitioning columns form a subset of the
index columns. This restriction guarantees that rows with identical index keys always
map into the same partition, where uniqueness violations can be detected.
Local indexes have the following advantages:
Only one index partition needs to be rebuilt when a maintenance operation
(other than SPLIT PARTITION, or ADD PARTITION for a hash partition) is
performed on an underlying table partition.
o The duration of a partition maintenance operation remains proportional
to partition size if the partitioned table has only local indexes.
o Local indexes support partition independence.

o Local indexes support smooth roll-out of old data and roll-in of new data
in historical tables.
Oracle can take advantage of the fact that a local index is equipartitioned with
the underlying table to generate better query access plans.
Local indexes simplify the task of tablespace incomplete recovery. In order to
recover a partition or subpartition of a table to a point in time, you must also
recover the corresponding index entries to the same point in time. The only way
to accomplish this is with a local index; then you can recover the corresponding
table and index partitions or subpartitions together.
You can build or rebuild local indexes on partitioned tables using intrapartition
parallelism (that is, multiple processes for each partition) with the
BUILD_PART_INDEX procedure of the DBMS_PCLXUTIL package.
Additional Information:
See Oracle8i Supplied Packages Reference for a description of the
DBMS_PCLXUTIL package.

Local Prefixed Indexes

A local index is prefixed if it is partitioned on a left prefix of the index columns.


For example, if the SALES table and its local index SALES_IX are partitioned on the
WEEK_NUM column, then index SALES_IX is local prefixed if it is defined on the
columns (WEEK_NUM,XACTION_NUM). On the other hand, if index SALES_IX is
defined on column PRODUCT_NUM then it is not prefixed.
Figure 11-4 shows another example of a local prefixed index.
Local prefixed indexes can be unique or nonunique.
Figure 11-4 Local Prefixed Index

Local Nonprefixed Indexes

A local index is nonprefixed if it is not partitioned on a left prefix of the index


columns.
You cannot have a unique local nonprefixed index unless the partitioning key is a
subset of the index key.
Figure 11-5 shows an example of a local nonprefixed index.
Figure 11-5 Local Nonprefixed Index

Global Partitioned Indexes

In a global partitioned index, the keys in a particular index partition may refer to rows
stored in more than one underlying table partition or subpartition. A global index can
only be range-partitioned, but it can be defined on any type of partitioned table (range,
hash, or composite partitioned).
A global index is created by specifying the GLOBAL attribute. The database
administrator is responsible for defining the initial partitioning of a global index at
creation and for maintaining the partitioning over time. Index partitions can be merged
or split as necessary.
Normally, a global index is not equipartitioned with the underlying table. There is
nothing to prevent an index from being equipartitioned with the underlying table, but
Oracle does not take advantage of the equipartitioning when generating query plans or
executing partition maintenance operations. So an index that is equipartitioned with
the underlying table should be created as LOCAL.
A global partitioned index contains (conceptually) a single B*-tree with entries for all
rows in all partitions. Each index partition may contain keys that refer to many
different partitions or subpartitions in the table.
The highest partition of a global index must have a partition bound all of whose
values are MAXVALUE. This insures that all rows in the underlying table can be
represented in the index.
Prefixed and Nonprefixed Global Partitioned Indexes

A global partitioned index is prefixed if it is partitioned on a left prefix of the index


columns. (See Figure 11-6 for an example.) A global partitioned index
is nonprefixed if it is not partitioned on a left prefix of the index columns. Oracle does
not support global nonprefixed partitioned indexes.
Global prefixed partitioned indexes can be unique or nonunique.
Nonpartitioned indexes are treated as global prefixed nonpartitioned indexes.
Management of Global Partitioned Indexes

Global partitioned indexes are harder to manage than local indexes:


When the data in an underlying table partition is moved or removed (SPLIT,
MOVE, DROP, or TRUNCATE), all partitions of a global index are affected.
Consequently global indexes cause partition maintenance (including rebuilds of
global indexes or index partitions) to have duration proportional to table size
rather than partition size, and they do not support partition independence.
When an underlying table partition or subpartition is recovered to a point in
time, all corresponding entries in a global index must be recovered to the same
point in time. Because these entries may be scattered across all partitions or
subpartitions of the index (mixed in with entries for other partitions or
subpartitions that are not being recovered), there is no way to accomplish this
except by re-creating the entire global index.
Figure 11-6 Global Prefixed Partitioned Index

Summary of Partitioned Index Types

Table 11-2 summarizes the three types of partitioned indexes that Oracle supports.
If an index is local, it is equipartitioned with the underlying table; otherwise it
is global.
A prefixed index is partitioned on a left prefix of the index columns; otherwise
it is nonprefixed.
Table 11-2 Types of Partitioned Indexes

Type of
Index

Index
Partitione UNIQUE
d on Left Attribut
Index
Prefix of
e
Table
Equipartitione
Index
Allowed Partitionin
d with Table Columns
g Key

Example
Index
Index
Column Partitionin
s
g Key

Local
Yes
Prefixed (any
partitioning
method)

Yes

Yes

A,B

Local
Yes
Nonprefixed
(any
partitioning
method)

No

Yes1

No2

Yes

Yes

--

--

--

--

--

Global
Prefixed
(range
partitioning
only)

Global
-Nonprefixed3

For a unique local nonprefixed index, the partitioning key must be a subset of the index key.
Although a global partitioned index may be equipartitioned with the underlying table, Oracle does not take
advantage of the partitioning or maintain equipartitioning after partition maintenance operations such as DROP or
SPLIT PARTITION.
3
This type of index is not supported.
2

Importance of Nonprefixed Indexes

Nonprefixed indexes are particularly useful in historical databases. In a table


containing historical data, it is common for an index to be defined on one column to
support the requirements of fast access by that column, but partitioned on another

column (the same column as the underlying table) to support the time interval for
rolling out old data and rolling in new data.
Consider the SALES table presented in Figure 11-1 ("SALES Table Partitioned by
Week"). It contains a year's worth of data, divided into 13 partitions. It is range
partitioned on WEEK_NO, four weeks to a partition. You might create a nonprefixed
local index SALES_IX on SALES. The SALES_IX index is defined on ACCT_NO
because there are queries that need fast access to the data by account number.
However, it is partitioned on WEEK_NO to match the SALES table. Every four
weeks the oldest partitions of SALES and SALES_IX are dropped and new ones are
added.
Performance Implications of Prefixed and Nonprefixed Indexes

It is more expensive to probe into a nonprefixed index than to probe into a prefixed
index.
If an index is prefixed (either local or global) and Oracle is presented with a predicate
involving the index columns, then partition pruning can restrict application of the
predicate to a subset of the index partitions.
For example, in Figure 11-4 ("Local Prefixed Index"), if the predicate is
DEPTNO=15, the optimizer knows to apply the predicate only to the second partition
of the index. (If the predicate involves a bind variable, the optimizer will not know
exactly which partition but it may still know there is only one partition involved, in
which case at run time, only one index partition will be accessed.)
When an index is nonprefixed, Oracle often has to apply a predicate involving the
index columns to all N index partitions. This is required to look up a single key, or to
do an index range scan. For a range scan, Oracle must also combine information from
N index partitions. For example, in Figure 11-5 ("Local Nonprefixed Index"), a local
index is partitioned on CHKDATE with an index key on ACCTNO. If the predicate is
ACCTNO=31, Oracle probes all 12 index partitions.
Of course, if there is also a predicate on the partitioning columns, then multiple index
probes might not be necessary. Oracle takes advantage of the fact that a local index is
equipartitioned with the underlying table to prune partitions based on the partition
key. For example, if the predicate in Figure 11-5 is CHKDATE<3/97, Oracle only has
to probe two partitions.

So for a nonprefixed index, if the partition key is a part of the WHERE clause (but not
of the index key) the optimizer determines which index partitions to probe based on
the underlying table partition.
When many queries and DML statements using keys of local, nonprefixed, indexes
have to probe all index partitions, this effectively reduces the degree of partition
independence provided by such indexes.
Guidelines for Partitioning Indexes

When deciding how to partition indexes on a table, consider the mix of applications
that need to access the table. There is a trade-off between performance on the one
hand and availability and manageability on the other. Here are some of the guidelines
you should consider:
For OLTP applications:
o Global indexes and local prefixed indexes provide better performance
than local nonprefixed indexes because they minimize the number of
index partition probes.
o Local indexes support more availability when there are partition or
subpartition maintenance operations on the table. Local nonprefixed
indexes are very useful for historical databases.
For DSS applications, local nonprefixed indexes can improve performance
because many index partitions can be scanned in parallel by range queries on
the index key.
For example, a query using the predicate "ACCTNO between 40 and 45" on the
table CHECKS of Figure 11-5 ("Local Nonprefixed Index") causes parallel
scans of all the partitions of the nonprefixed index IX3. On the other hand, a
query using the predicate "DEPTNO between 40 and 45" on the table DEPTNO
of Figure 11-4 ("Local Prefixed Index") cannot be parallelized because it
accesses a single partition of the prefixed index IX1.
For historical tables, indexes should be local if possible. This limits the impact
of regularly scheduled drop partition operations.
Unique indexes on columns other than the partitioning columns must be global
because unique local nonprefixed indexes whose key does not contain the
partitioning key are not supported.

Physical Attributes of Index Partitions

Default physical attributes are initially specified when a CREATE INDEX statement
creates a partitioned index. Since there is no segment corresponding to the partitioned
index itself, these attributes are only used in derivation of physical attributes of
member partitions. Default physical attributes can later be modified using ALTER
INDEX MODIFY DEFAULT ATTRIBUTES.
Physical attributes of partitions created by CREATE INDEX are determined as
follows:
Values of physical attributes specified (explicitly or by default) for the index
are used whenever the value of a corresponding partition attribute is not
specified. Handling of the TABLESPACE attribute of partitions of a LOCAL
index constitutes an important exception to this rule in that in the absence of a
user-specified TABLESPACE value, that of the corresponding partition of the
underlying table is used.
Physical attributes (other than TABLESPACE, as explained above) of partitions of
local indexes created in the course of processing ALTER TABLE ADD PARTITION
are set to the default physical attributes of each index.
Physical attributes (other than TABLESPACE, as explained above) of index partitions
created by ALTER TABLE SPLIT PARTITION are determined as follows:
Values of physical attributes of the index partition being split are used.
Physical attributes of an existing index partition can be modified by ALTER INDEX
MODIFY PARTITION and ALTER INDEX REBUILD PARTITION. Resulting
attributes are determined as follows:
Values of physical attributes of the partition before the statement was issued are
used whenever a new value is not specified. Note that ALTER INDEX
REBUILD PARTITION can be used to change the tablespace in which a
partition resides.
Physical attributes of global index partitions created by ALTER INDEX SPLIT
PARTITION are determined as follows:
Values of physical attributes of the partition being split are used whenever a
new value is not specified.

Physical attributes of all partitions of an index (along with default values) may be
modified by ALTER INDEX, for example, ALTER INDEX indexname NOLOGGING
changes the logging mode of all partitions of indexname to NOLOGGING.
See "Tablespace and Storage Attributes of LOB Index Partitions" for additional
information about the physical attributes of LOB index partitions.
Partitioning of Tables with LOB Columns
Tables that contain LOB columns (see "LOB Datatypes") can be partitioned; however,
a partitioning key cannot contain a LOB column. The LOB data and LOB index
segments of a LOB column are equipartitioned with the base table.
Note:
Although this section makes a distinction between the LOB data and LOB
index, they are not separate entities. The LOB index, which is implicitly
created and maintained by the system, contains control information and is an
integral part of LOB column storage.

For every partition of a partitioned table that contains a LOB column, there is a LOB
data segment for the LOB data partition and a LOB index segment for the LOB index
partition. These data and index segments contain the LOBs that belong to the rows in
that partition.
Similarly, for every subpartition of a composite-partitioned table that contains a LOB
column, there is a LOB data segment for the LOB data subpartition and a LOB index
segment for the LOB index subpartition. These data and index segments contain the
LOBs that belong to the rows in that subpartition. In the following discussion,
"partition" refers either to a partition of a range- or hash-partitioned table or index or
to a subpartition of a composite-partitioned table or index.
Equipartitioning of LOB data and LOB index segments localizes the effects of
maintenance operations, resulting in more efficient use of resources and improved
availability of data. See "Partition Maintenance Operations on Tables with LOB
Columns".

Tablespace and Storage Attributes of LOB Data Partitions

The algorithm for determining a tablespace for a given LOB data partition is similar to
that for determining a tablespace for a LOCAL index partition. In determining values
of physical storage attributes other than TABLESPACE for LOB data partitions,
Oracle uses the same algorithm that determines the values of physical attributes for
table partitions. Note that you can explicitly specify the LOB storage characteristics
for a specific LOB column at the partition level or at the table level.
TABLESPACE Attribute of LOB Data Partitions

The following rules determine the tablespace of a LOB data partition:


1 If a tablespace is specified for a given LOB data partition, that value is used.
1 Otherwise, if a default TABLESPACE value, other than "TABLESPACE
DEFAULT", is specified at the table level for all LOB data partitions of a given
LOB column of the table, that value is used.
1 Otherwise, the LOB data partition is co-located with the table partition to
which it corresponds.
The following example illustrates these rules:
CREATE TABLE PT1 (A NUMBER, B BLOB, C CLOB, D CLOB)
LOB (B,D) STORE AS (STORAGE (NEXT 15K))
LOB (C) STORE AS (TABLESPACE TSB)
PARTITION BY RANGE (A)
(PARTITION P VALUES LESS THAN (MAXVALUE) TABLESPACE TS1
LOB (B) STORE AS (TABLESPACE TSA),
LOB (C) STORE AS (PCTVERSION 20),
LOB (D) STORE AS (STORAGE (NEXT 10K)))
TABLESPACE TSX;

(Rule 1)
(Rule 2)
(Rule 3)

In this example, the tablespace for the LOB data partitions corresponding to partition
P are determined as follows:
The LOB data partition for column B is located in tablespace TSA (Rule 1).
The LOB data partition for column C is located in tablespace TSB (Rule 2).
The LOB data partition for column D is located in tablespace TS1 (Rule 3).

See "Tablespace and Storage Attributes of LOB Index Partitions" for a discussion of
how to determine a tablespace in which a LOB index partition is located.
Other Storage Attributes of LOB Data Partitions

The values of the storage attributes (other than TABLESPACE) for a LOB data
partition are determined as follows:
1 If a value is specified for a given LOB data partition, that value is used.
1 Otherwise, if a default value is specified at the table level for all LOB data
partitions of a given LOB column of the table, that value is used.
1 Otherwise, the system or tablespace default value is used. However, in the case
of LOGGING, if CACHE is explicitly specified then LOGGING is used
regardless of the tablespace value (because CACHE NOLOGGING is not
supported).
See the next section for a discussion of how the storage attributes for a LOB index
partitions are determined.
Tablespace and Storage Attributes of LOB Index Partitions

LOB index partitions always reside in the same tablespace as the LOB data partitions
to which they correspond, that is, the LOB index partitions are co-located with the
LOB data partitions. All other attributes of a LOB index partition are determined
based on attributes of the LOB data partition to which they correspond and default
attributes of the tablespace in which both the LOB data and its corresponding LOB
index partition reside.
Note:
You cannot specify any attributes for a LOB index or any of its partitions.

TABLESPACE Attribute of LOB Index Partitions

The following example shows how LOB index partitions collocate with the LOB data
partitions to which they correspond:

CREATE TABLE PT1 (A NUMBER, B BLOB, C CLOB, D CLOB)


LOB (B,D) STORE AS (STORAGE (NEXT 15K))
LOB (C) STORE AS (TABLESPACE TSB);
PARTITION BY RANGE (A)
(PARTITION P VALUES LESS THAN (MAXVALUE) TABLESPACE TS1
LOB (B) STORE AS (TABLESPACE TSA),
LOB (C) STORE AS (PCTVERSION 20),
LOB (D) STORE AS (STORAGE (NEXT 10K)))
TABLESPACE TSX;

(Rule 1)
(Rule 2)
(Rule 3)

In this example, the LOB index partitions that correspond to LOB data partitions
associated with partition P are located in the following tablespaces:
The LOB index partition for column B is located in tablespace TSA (Rule 1).
The LOB index partition for column C is located in tablespace TSB (Rule 2).
The LOB index partition for column D is located in tablespace TS1 (Rule 3).
Other Storage Attributes of LOB Index Partitions

The values of the storage attributes (other than TABLESPACE) for a LOB index
partition are determined based on the values of attributes of a corresponding LOB data
partition and the default attributes of the tablespace in which the LOB index partition
is located.
Views and Partitioned LOBs

Regular views on partitioned tables with LOB columns work the same way that they
do on tables without LOB columns. Object views can also be created on top of
partitioned tables with LOB columns.
The same view-based privilege checking is performed on LOBs selected from views
on partitioned tables as for LOBs selected from views on nonpartitioned tables. The
user must have privileges to access the LOB through the view from which the LOB
locator is obtained (SELECTed). This view-based privilege checking is necessary for
snapshots (that is, materialized views used for replication).
BFILEs in Partitioned Tables

For BFILEs, only the LOB locator is stored in the table while the actual BFILE data
exists in an external operating system file. Therefore the BFILE locator is what gets
partitioned with the rest of the table, not the BFILE data. The BFILE locator is of
varying length and stores the directory alias and file name along with other control

information. Thus, a BFILE column in a partitioned table is similar to a VARCHAR2


column in a partitioned table.
Partitioning Index-Organized Tables and Their Secondary Indexes
You can partition an index-organized table by range of column values. An indexorganized table differs from a regular (heap-organized) table in the following ways:
An index-organized table always has a primary key, whereas a regular table
may not have a primary key.
The rows of an index-organized table are stored in the leaf blocks of primary
key index segment as part of the index row.
An index-organized table can optionally have a row overflow data segment in
addition to the primary key index segment. Thus, a regular table (without
LOBs) is stored in a single data segment, whereas an index-organized table
(without LOBs) requires an index segment and (optionally) an overflow data
segment to store the data.
See "Index-Organized Tables" for more information.
When partitioning an index-organized table, note the following:
Only range partitioning is supported.
Partition columns must be a subset of the primary key columns.
Secondary indexes may also be partitioned, both locally and globally.
OVERFLOW data segments are always equipartitioned with the table
partitions.
Storage attributes can be specified at the table level or individual partition level
for both table data and overflow data.
Range Partitioning and Primary Key Columns

Restricting the partitioning columns to a subset of the primary key columns ensures
that when you insert a row into a partition, the uniqueness of the primary key can be
verified by searching that partition. (Without this restriction, it would be necessary to

search other partitions as well, and so the partitions would not be independent of each
other.)
When the partitioning columns form a prefix of the primary key columns, the partition
bounds form a sequence in primary key order. For queries that require data from more
than one partition, a simple concatenation of resulting rows from each partition
preserves the primary key order. This is the optimal way of partitioning an indexorganized table.
When the partitioning columns do not form a prefix of the primary key columns, each
partition's data is sorted in primary key order but selecting rows from more than one
partition in primary key order requires a merge of the individually sorted partition
rows.
If you want to partition an index-organized table on columns that are not a subset of
the primary key columns, you can use this workaround:
1 Make the partitioning columns part of the primary key by adding them at the
end.
1 Define a unique constraint on the original primary key columns.
For example, for an index-organized table that has columns A, B, and C with a
primary key (A, B), if you want to partition the table on column C you should change
the primary key to (A, B, C) and define a unique constraint on (A, B). Then an insert
operation will insert the row into the target partition and insert the key values for
(A,B) into a nonpartitioned index on (A,B), which verifies the uniqueness across all
the partitions.
Index-Organized Tables without Row Overflow

To create a partitioned index-organized table without row overflow, you need to


specify ORGANIZATION INDEX at the table level only. All partitions inherit the
ORGANIZATION INDEX property from the table.
You can specify default values for physical attributes at the table level and can
override them at the partition level. These attributes apply to the primary key index
segment that is created for each partition. The tablespace for an index segment can be
specified at the partition level or at the table level; if it is not specified at either level,
the user's default tablespace is used.

The following example shows the creation of an index-organized table with no row
overflow:
CREATE TABLE orders(
id NUMBER, odate DATE, ...
PRIMARY KEY(id, odate))
ORGANIZATION INDEX
PARTITION BY RANGE(odate)
( PARTITION p1 ... TABLESPACE q1,
PARTITION p2 ... TABLESPACE q2);

In this example, the index organized table ORDERS is range partitioned on the
ODATE column, with each partition stored in its own tablespace. No overflow is
provided for.
Index-Organized Tables with Row Overflow

The overflow option allows storing the tail portion of a row in an overflow data
segment. The following are the key aspects for partitioned index-organized tables with
overflow:
For partitioned index-organized tables with overflow, each partition has an
index segment and an overflow data segment.
The overflow data segments are equipartitioned with the primary key index
segments.
Like physical attributes for the index segment, you can specify default values
for physical attribites for the overflow data segments at the table level and can
override them by specifying partition-level values.
All the attributes prior to the OVERFLOW keyword apply to the primary key
index segment, and all the attributes after the OVERFLOW keyword apply to
the overflow data segment.
The default values for PCTTHRESHOLD and INCLUDING column can only
be specified at the table level. These clauses control the breaking of the the
non-key portion into head and tail row-pieces. The head row-piece is stored in
the index row and the tail row-piece is stored in the overflow data segment.
The tablespace for an overflow data segment if not specified for a partition is
set to the table-level default. If the table-level default is not specified, then the
tablespace of the corresponding partition's index segment is used.

The system-generated names for the index and overflow data segment are of
the form SYS_IOT_TOP_Pn and SYS_IOT_OVER_Pn, respectively.
The following example shows the creation of a partitioned index-organized table with
partitioned overflow stored in a single tablespace:
CREATE TABLE orders(
id NUMBER, odate DATE, notes VARCHAR2(1000), ...
PRIMARY KEY(id, odate))
ORGANIZATION INDEX INCLUDING odate
OVERFLOW TABLESPACE all_overflow
PARTITION BY RANGE(odate)
( PARTITION p1 ... TABLESPACE q1,
PARTITION p2 ... TABLESPACE q2);

In this example, the table has a separate tablespace for overflow data segments. Even
though they are stored in the same physical tablespace (ALL_OVERFLOW), the
overflow data segments are partitioned on the same partition columns as used in the
index-organized table. Note the use of the INCLUDING ODATE clause--this means
that all data, past and including the ODATE column, will be stored in the overflow.
The following example shows the creation of a partitioned index-organized table with
partitioned overflow stored in multiple tablespaces:
CREATE TABLE orders(
id NUMBER, odate DATE, notes VARCHAR2(1000), ...
PRIMARY KEY(id, odate))
ORGANIZATION INDEX INCLUDING odate
PARTITION BY RANGE(odate)
( PARTITION p1 ... TABLESPACE q1
OVERFLOW TABLESPACE q1_overflow,
PARTITION p2 ... TABLESPACE q2
OVERFLOW TABLESPACE q2_overflow);

In this example, each partitioned overflow segment is stored in its own tablespace.
Partitioned Secondary Indexes on Index-Organized Tables

You can create local prefixed, local non-prefixed, and global prefixed partitioned
indexes on index-organized tables. Indexes on index-organized tables store primary
key-based (logical) rowids as opposed to physical rowids, and may contain additional
"guess"data as part of the rowid to speed up secondary index-based access.
See "Secondary Indexes on Index-Organized Tables" and "Logical Rowids" for more
information.

For accessing an index-organized table partition by its global partition index, Oracle
identifies the partition based on the logical rowid. This is possible because the rowid
contains primary key columns, which in turn contain all of the partitioning columns.
Once the partition is identiifed, Oracle can use the "guess" to directly access the leaf
block that would hold the index row. If the "guess" is invalid, an index scan on the
relevant partition B*-tree is required.

DML Partition Locks and Subpartition Locks


DML table locks synchronize DML statements (INSERT, UPDATE, and DELETE)
with DDL statements and LOCK TABLE statements. DML table locks also
synchronize DDL and LOCK TABLE statements among themselves. For partitioned
or subpartitioned tables, Oracle uses DML partition locks or DML subpartition locks
to provide partition independence for DDL and utility operations.
Range partitioned or hash partitioned tables have DML partition locks.
Tables that use composite partitioning have DML subpartition locks.
Partition independence (or subpartition independence) allows you to perform DDL
and utility operations on selected partitions or subpartitions without reducing activity
on other partitions or subpartitions.
DML Partition Locks
A partition lock protects the data in an individual partition of a partitioned table while
multiple users are accessing that partition or other partitions in the table concurrently.
Partition locks fall between table locks and row locks in the DML locking hierarchy:
Table locks
o Partition locks
Row locks
Partition locks can be acquired in the same modes as table locks: Share (S), Exclusive
(X), Row Share (SS), Row Exclusive (SX), and Share Row Exclusive (SSX).
See "Concurrency Model for Maintenance Operations" for more information about
partition locking for DML and DDL statements.
Partition Locking During DML Operations on LOB Columns

When updating a LOB as a whole or only partially (using DBMS_LOB operations), in


addition to acquiring a DML SX-lock on a partitioned table, Oracle acquires DML
SX-lock(s) on one or more table partitions.
DML Subpartition Locks
DML subpartition locks allow you to perform DDL and utility operations on selected
subpartitions without reducing activity on other subpartitions of the same partition (as
well as on subpartitions of other partitions.)
A subpartition lock protects the data in an individual subpartition while multiple users
are accessing that subpartition or other subpartitions in the same partition, or some
subpartitions in other partitions of the table concurrently.
Oracle does not acquire DML partition locks when performing DML or DDL
operations on composite partitioned tables:
A DML operation accessing data in a given subpartition acquires a DML lock
on that subpartition in the same mode as a similar DML operation accessing
data in a partition of a range partitioned table or hash partitioned table.
A subpartition maintenance operation acquires DML locks on subpartitions
involved in the operation.
A maintenance operation on a partition of a composite partitioned table (for
example, SPLIT PARTITION or TRUNCATE PARTITION) acquires DML
locks on all subpartitions belonging to the partition involved in the operation.
As with partition locks, subpartition locks fall between table locks and row locks in
the DML locking hierarchy:
Table locks
o Subpartition locks
Row locks
Subpartition DML locks can be acquired in the same modes as table and partition
DML locks: Share (S), Exclusive (X), Row Share (SS), Row Exclusive (SX), and
Share Row Exclusive (SSX).
Performance Considerations for Oracle Parallel Server

Introducing an extra level of DML locking may affect the performance of short
transactions in the Oracle Parallel Server environment because extra messages are
sent to the Distributed Lock Manager.
To improve performance in the Oracle Parallel Server environment, you can turn off
DML locking on selected tables with the ALTER TABLE DISABLE TABLE LOCK
statement, which disables both table and partition DML locks. DDL statements are not
allowed when DML locking is disabled.
Additional Information:
See Oracle8i Parallel Server Concepts and Administration.

Maintenance Operations
This section covers the following topics:
Partition Maintenance Operations
Managing Indexes
Privileges for Partitioned Tables and Indexes
Auditing for Partitioned Tables and Indexes
For the purposes of this chapter, a maintenance operation is a DDL statement that
alters a table or index definition or a utility (such as Export, Import, or SQL*Loader)
that performs bulk load or unload of data.
Most maintenance operations on nonpartitioned tables and indexes also work on
partitioned tables and indexes. For example, DROP TABLE can drop a partitioned
table, and Export can export a partitioned table. However, some maintenance
operations must be performed on individual partitions rather than the whole
partitioned table or index. For example, ALTER TABLE ALLOCATE EXTENT
cannot be used for a range-partitioned table; instead, you use ALTER TABLE
MODIFY PARTITION ALLOCATE EXTENT for the partition or partitions that need
new extents.

Maintenance operations are considered fast if their expected duration is not affected
by the size (number of records) of the schema objects they operate upon. Fast
maintenance operations result only in dictionary and segment header changes, and do
not cause data scans and data updates. They are expected to complete in a short time
(order of seconds). For example, RENAME is a fast operation while CREATE
INDEX is not a fast operation.
Partition Maintenance Operations
A partition maintenance operation modifies one partition of a partitioned table or
index. For example, you might add a new partition to an existing table, or you might
move a partition to a different tablespace for better I/O load balancing, or you might
load a partition.
Some partition maintenance operations are planned events. For example, in a
historical database, the database administrator (DBA) periodically drops the oldest
partitions from the database and adds a set of new partitions. This drop and add
operation occurs on a regularly scheduled basis. Another example of a planned
maintenance operation is a periodic Export/Import to recluster data and reduce
fragmentation.
Other partition maintenance operations are unplanned events, required to recover from
application or system problems. For example, unexpected transaction activity may
force the DBA to split a partition to rebalance I/O load, or the DBA may need to
rebuild one or more index partitions.
The partition maintenance operations are:
add a table partition or subpartition to an existing table
merge table partitions (range or composite partitioning)
coalesce table partitions (hash partitioning) or subpartitions (composite
partitioning)--redistribute the contents of a partition or subpartition into one or
more remaining partitions or subpartitions
split an existing partition into two partitions (range or composite partitioning)
drop a partition (range or composite partitioning)
truncate a table partition or subpartition (with or without reclaiming space)

exchange a partition or subpartition--swap the data (and possibly local index


segments) of a table partition or subpartition with the data (and index segments)
of a non-partitioned table
modify a partition or subpartition--change the physical attributes of a partition
or subpartition
modify default attributes for a partition (composite partitioning)--specify
default attributes for new subpartitions of a partition
move a table partition or subpartition--move it to another tablespace, or
recluster it, or change any of its parameters (including any of its create-time
parameters)
rename a partition or subpartition
mark all local index partitions or subpartitions associated with a table partition
or subpartition as UNUSABLE
rebuild an index partition or subpartition
load data into one table partition or subpartition
export data from one table partition or subpartition
import a table partition or subpartition
For information about maintenance of LOB data, see "Partition Maintenance
Operations on Tables with LOB Columns".
Additional Information:
See ALTER TABLE and ALTER INDEX in the Oracle8i SQL Reference for
detailed information about partition maintenance operations.

Concurrency Model for Maintenance Operations

The concurrency model described in this section defines when it is possible to run
more than one DDL and utility operation on the same schema object at the same time.
It also defines which query and DML operations can be run concurrently with DDL
and utility operations.
The model applies to all DDL statements. It also applies to utilities like SQL*Loader.
One-Step and Three-Step Operations

There are two types of maintenance operations, one-step and three-step.


One-step operations:
These operations DML lock the affected table in Exclusive (X) mode. Index
operations lock the underlying table. They also hold Exclusive dictionary locks
for the duration of the operation.
These operations are either fast (for example, ALTER TABLE ADD
PARTITION for range partitioning) or they offer no possibility of running other
operations concurrently (for example, ALTER TABLE ADD column).
All index operations are one-step except:
o CREATE INDEX and ALTER INDEX REBUILD
o ALTER INDEX DROP or SPLIT PARTITION, if the global partition
being dropped or split is USABLE
All Oracle DDL statements are one-step except:
o CREATE INDEX
o MOVE, SPLIT, or REBUILD PARTITION or SUBPARTITION
o EXCHANGE PARTITION or SUBPARTITION WITH VALIDATION
o ADD PARTITION for hash partitioning and ADD SUBPARTITION for
composite partitioning (this is processed the same way as the SPLIT and
MOVE PARTITION or SUBPARTITION operations)
o COALESCE PARTITION or SUBPARTITION

o LOAD, EXPORT, or IMPORT PARTITION or SUBPARTITION


For composite-partitioned tables and local indexes, all partition maintenance
operations follow the same protocol as similar operations on range-partitioned
tables and local indexes.
Three-step operations:
These operations acquire less restrictive DML locks on the affected table. They
lock only one partition or subpartition in Exclusive (X) mode, or if they lock
the entire table, they lock it in an S or SS or SX mode.
These operations consist of three steps:
o Step 1: read dictionary while holding Share dictionary locks. Step 1
takes a short time (seconds). At the end of this step, the appropriate DML
locks are acquired, then the dictionary locks are released.
o Step 2: scan or update table or index records. Step 2 may take a long
time (minutes or hours).
o Step 3: update dictionary while holding Exclusive dictionary locks. Step
3 takes a short time (seconds).
These operations are long running, but they allow other operations to run
concurrently. Exactly which operations can run concurrently depends on the
specific DML locks acquired by the statement, as explained below.
If a three-step operation on range-partitioned tables or local indexes acquires
DML locks on partitions, the same operation on composite-partitioned tables or
local indexes also acquires locks on all subpartitions of each partition involved
in the operation.
The following operations are three-step:
o ALTER TABLE MOVE PARTITION or SUBPARTITION, ALTER
TABLE SPLIT PARTITION, ALTER TABLE EXCHANGE
PARTITION or SUBPARTITION WITH VALIDATION, Direct Path
Load Table Partition or Subpartition: These statements lock the table in
Row Exclusive (SX) mode and the partition or subpartition in Exclusive
(X) mode.

o CREATE INDEX and ALTER INDEX REBUILD PARTITION (for a


global index): These statements lock the table in Shared (S) mode.
o ALTER INDEX REBUILD PARTITION or SUBPARTITION (for a
local index): This statement locks the table in Row Share (SS) mode and
the partition or subpartition in Shared (S) mode.
o ALTER TABLE MODIFY PARTITION REBUILD UNUSABLE
LOCAL INDEXES: This statement locks the table in Row Share (SS)
mode and the partition in Shared (S) mode.
o ALTER TABLE MODIFY PARTITION ADD SUBPARTITION. This
statement locks the table in Row Exclusive (SX) mode and the
subpartition in Exclusive (X) mode.
o ALTER TABLE COALESCE PARTITION. This statement locks the
table in Row Exclusive (SX) mode and locks the last partition of the
table and the partition into which rows from the last partition will be
rehashed in Exclusive (X) mode.
o ALTER TABLE MODIFY PARTITION COALESCE SUBPARTITION.
This statement locks the table in Row Exclusive (SX) mode and locks
the last subpartition of the partition and the subpartition into which rows
from the last subpartition will be rehashed in Exclusive (X) mode.
o LOAD PARTITION or SUBPARTITION. When run sequentially, this
statement locks the table in Row Exclusive (SX) mode and the partition
or subpartition being loaded in Exclusive (X) mode. When run in
parallel, it locks the table in Row Share (SS) mode and the partition or
subpartition being loaded in Shared (S) mode.
o EXPORT PARTITION or SUBPARTITION. This statement acquires no
DML locks (it runs a SELECT from a partition or subpartition).
o IMPORT PARTITION or SUBPARTITION. This statement locks the
table and the partition or subpartition into which data is being imported
(by INSERT into a subpartition) in Row Exclusive (SX) mode.
Finally, some operations may follow either one-step or three-step protocol:

ALTER TABLE DROP PARTITION and ALTER TABLE TRUNCATE


PARTITION
If the table being altered has no global indexes defined on it, or if it is
referenced by enabled referential constraints, statements in this group execute
using the one-step protocol and they are fast. Otherwise, they execute using the
three-step protocol. In the latter case, the base table is locked in Row Exclusive
(SX) mode and the partition is locked in Exclusive (X) mode.
ALTER INDEX SPLIT PARTITION (allowed for global indexes only)
If the partition to be split is USABLE, the statement follows the 3-step
protocol, and partitions resulting from the SPLIT are USABLE. If, on the other
hand, the partition being split is UNUSABLE, the operation follows the 1-step
protocol, and resulting partitions are also marked UNUSABLE.
ALTER INDEX DROP PARTITION (allowed for global indexes only)
If the partition to be dropped is USABLE, the statement follows the three-step
protocol; otherwise it follows the one-step protocol.
Conventional Path SQL*Loader and Import use SQL INSERT so they are classified as
DML operations for the purposes of the model. Export uses SQL SELECT so it is
classified as a query operation.
Operations That Can Run Concurrently

The rules in this section can be derived from the definitions of one-step and three-step
operations.
While a one-step operation is in progress:
You can run queries on the table.
You cannot run any other operation (DDL, utility, or DML).
Since queries (READ operations) do not take DML locks, queries are allowed on a
partition which is being split or moved while the SPLIT or MOVE is being processed.
However, the current segments are dropped at the end of the operation, and the space
may be reused. An error is signalled if the space is reused.

While an ALTER TABLE MOVE PARTITION, ALTER TABLE SPLIT PARTITION,


ALTER TABLE EXCHANGE PARTITION, or Direct Path Load Table Partition is in
progress on a partition:
You can move, split, exchange, or direct path load other partitions in the same
table.
You can run queries on the table.
You can execute DML operations on the table provided that they do not write to
that partition.
You can rebuild any local index partition other than the ones that correspond to
that partition.
You cannot run any maintenance operation on the table or its indexes other than
the ones listed above.
While a CREATE INDEX or ALTER INDEX REBUILD PARTITION or ALTER
INDEX DROP/SPLIT PARTIITON applied to a USABLE partition (for a global
index) is in progress:
You can run queries on the underlying table.
You can create other indexes on the table, rebuild partitions in existing indexes,
or drop or split USABLE partitions in existing indexes.
You cannot execute any DML operation on the table or run any maintenance
operation on the table or its indexes other than the ones listed above.
While an ALTER INDEX REBUILD PARTITION (for a local index) is in progress on
a partition which corresponds to an underlying table partition:
You can move, split, or direct path load any partition except the underlying
table partition.
You can run queries on the table.
You can execute DML operations on the table provided that they do not write to
the underlying table partition.

You can rebuild other partitions in the index. You can also create other indexes
on the table or rebuild partitions in other indexes.
You cannot run any maintenance operation on the table or its indexes other than
the ones listed above.
Some maintenance operations on a partition of a table cause the global indexes of the
table or the index partitions to become UNUSABLE. An example is ALTER TABLE
MOVE PARTITION. The DBA has to run a script that includes global index rebuilds
in addition to the partition maintenance operation. Consequently from a user point of
view these operations serialize access to the entire table. Operations such as ALTER
TABLE MOVE/SPLIT PARTITION make UNUSABLE any nonpartitioned global
indexes as well as all partitions of partitioned global indexes.
Note that table partition operations which mark all partitions of global indexes also
mark one partition of local index (the partition corresponding to the table partition
being operated on) UNUSABLE.
Similarly some partition maintenance operations require disabling Referential
Integrity Constraints before the operation, and re-enabling them afterwards. An
example is a ALTER TABLE DROP PARTITION of a nonempty partition. The DBA
has to run a script that includes constraint re-enabling in addition to the partition
maintenance operation. Consequently, from a user point of view these operations
serialize access to the entire table.
Table 11-3 shows the operations that can be performed concurrently with maintenance
operations on subpartitions.

Table 11-3 Concurrent Operations on Subpartitions

Maintenance Operation
ALTER TABLE/INDEX MODIFY
DEFAULT ATTRIBUTES OF
PARTITION
ALTER TABLE EXCHANGE
SUBPARTITION WITHOUT

Operations That Can Be Performed


Concurrently
Queries on the table

Maintenance Operation

Operations That Can Be Performed


Concurrently

VALIDATION
ALTER TABLE/INDEX MODIFY
SUBPARTITION (unless
ALLOCATE EXTENT is specified)
ALTER TABLE/INDEX RENAME
SUBPARTITION

ALTER TABLE MODIFY


Queries on the table
PARTITION ADD SUBPARTITION
DML as long as no attempt is made to modify contents
ALTER TABLE MODIFY
of the subpartitions affected by the statement
PARTITION COALESCE
SUBPARTITION
Maintenance operations on other partitions and their
subpartitions
Maintenance operations on other subpartitions of the
partition
ALTER INDEX REBUILD SUBPARTITION on
subpartitions of local indexes corresponding to other
subpartitions of the same partition or to subpartitions of
other partitions of the table

ALTER TABLE EXCHANGE


SUBPARTITION WITH
VALIDATION

Queries on the table


DML as long as no attempt is made to modify contents
of the subpartition(s) referenced by the statement

ALTER TABLE/INDEX MODIFY


SUBPARTITION ALLOCATE
EXTENT

Maintenance operations on other partitions and their


subpartitions

ALTER TABLE MOVE


SUBPARTITION

Maintenance operations on other subpartitions of the


partition

LOAD SUBPARTITION

ALTER INDEX REBUILD SUBPARTITION on


subpartitions of local indexes corresponding to other
subpartitions of the same partition or to subpartitions of

Maintenance Operation

Operations That Can Be Performed


Concurrently
other partitions of the table

IMPORT SUBPARTITION

Queries on the table


DML on the table
Maintenance operations on other partitions and their
subpartitions
Maintenance operations on other subpartitions of the
partition
ALTER INDEX REBUILD SUBPARTITION on
subpartitions of local indexes corresponding to other
subpartitions of the same partition or to subpartitions of
other partitions of the table

EXPORT PARTITION

Any operation on the table and indexes defined on it,


their partitions, and subpartitions

ALTER (local) INDEX REBUILD


SUBPARTITION

Queries on the table


DML as long as no attempt is made to modify contents
of the subpartition corresponding to the index
subpartition being rebuilt
Maintenance operations on subpartitions of the index's
partitions, other than the partition whose subpartition is
being rebuilt
Maintenance operations on other subpartitions of the
index partition
CREATE new indexes on the underlying table
Maintenance operations on existing indexes on the
underlying table, as well as their partitions and

Maintenance Operation

Operations That Can Be Performed


Concurrently
subpartitions (if applicable)
Maintenance operations on partitions of the underlying
table, other than the partition corresponding to the index
partition whose subpartition is being rebuilt
Maintenance operations on subpartitions of the
underlying table, other than the one corresponding to the
index subpartition being rebuilt

Partition Maintenance Operations on Tables with LOB Columns

Table partition maintenance operations handle partitioned tables with LOB columns
(see "Partitioning of Tables with LOB Columns") as follows:
ADD PARTITION: For every LOB column in a table, a new LOB data
partition and LOB index partition are created. You can specify the physical
attributes of the new LOB data partitions.
DROP PARTITION: For every LOB column in a table, the LOB data partition
and LOB index partition corresponding to the table partition being dropped are
also dropped.
EXCHANGE PARTITION: The algorithm used to determine whether a given
nonpartitioned table may be exchanged with a partition of a partitioned table
can also handle LOB columns.
IMPORT/EXPORT PARTITION: You can import/export partitions of tables
containing LOB column(s).
LOAD PARTITION: In addition to loading data into the table partition, data is
also loaded into LOB data partitions (while making appropriate changes to
LOB index partitions) corresponding to that table partition.
MODIFY PARTITION: You can modify attributes of LOB data partitions
associated with a given table partition. Although you cannot specify attributes

for a LOB index partition, changes to an attribute of a LOB data partition may
result in changes to the corresponding attribute of a LOB index partition
associated with it.
MOVE PARTITION: For every LOB column in a table, a LOB data partition
and LOB index partition corresponding to the table partition being moved can
also be moved (although they do not have to be moved, for example, if a LOB
data partition resides on a read-only device). You can specify new physical
attributes of LOB data partitions.
SPLIT PARTITION: For every LOB column in a table, two new LOB data
partitions and LOB index partitions are created. LOB instances are divided
between the new partitions based on the values of the partitioning column(s) in
the row of which they are a part. You can specify physical attributes for the new
LOB data partitions.
TRUNCATE PARTITION: For every LOB column in a table, the LOB data
partition and LOB index partition corresponding to the table partition being
truncated are also truncated.
Addition of LOB columns to partitioned tables has no effect on the concurrency
model for maintenance operations (see "Concurrency Model for Maintenance
Operations").
Queries and Partition Maintenance Operations

Queries whose execution starts before invocation of a partition maintenance


operation, or before dictionary updates are done during a partition maintenance
operation, correctly access via Consistent Read the data of the affected partitions as
existing at query snapshot time. Such queries either successfully complete returning
all relevant data as present at snapshot time, or fail to complete returning error ORA8103 or ORA-1410. The application should reissue the query if one of these errors is
returned.
Queries that use a partitioned index, and that start with some of the index partitions
marked as INDEX UNUSABLE, return an error when they actually access one of
these partitions for the first time. This happens even if the partition has been made
USABLE after query start.
Cursor Invalidation

Although many of the new DDL statements are partition-based, cursor invalidation is
still table-based. This means that any DDL statement that modifies table T also
invalidates all cursors that depend on T, even if the statement affects only one
partition P of T and the cursors do not access partition P.
LOGGING and NOLOGGING Operations

All partition maintenance operations can be run in LOGGING mode. However, some
operations support a NOLOGGING option:
Parallel CREATE TABLE ... AS SELECT
CREATE INDEX
SPLIT, MOVE, or REBUILD PARTITION
Direct Path SQL*Loader
Direct-load INSERT
LOGGING is the default, except when the database operates in NOARCHIVELOG
mode in which case NOLOGGING is the default. DDL and utility statements that do
not support the LOGGING/NOLOGGING option always run in recoverable mode
(LOGGING).
Note:
LOGGING or NOLOGGING is not an attribute of an operation but of a
physical object; hence, you cannot specify LOGGING or NOLOGGING in
an INSERT statement. Instead, if you want to alter the logging mode of a
table or index(es) involved in an insert operation, you need to issue ALTER
TABLE/INDEX [NO]LOGGING before issuing the INSERT statement. For
more information, see "Logging Mode".

Managing Indexes

You can always rename, change the physical storage attributes, or rebuild a partition
of a local or global index. Changing how an index is partitioned must be handled
differently depending on whether the index is local or global.
Local Indexes

Oracle guarantees that the partitioning of a local index matches the partitioning of the
underlying table. It does this by automatically creating or dropping index partitions as
necessary when you alter the underlying table. You cannot explicitly add, drop, or
split a partition in a local index.
For each local index:
When you add a partition to the underlying table, Oracle automatically creates
a new index partition with the same partition bound as the new table partition.
When you drop a partition in the underlying table, Oracle automatically drops
the corresponding index partition.
When you split a partition in the underlying table, Oracle automatically splits
the corresponding index partition. The two new index partitions have the same
partition bounds as the new table partitions.
Note that local index partitions produced as a result of splitting a parent table
partition are marked UNUSABLE if a corresponding table partition is
nonempty.
When Oracle creates a new local index partition (via ADD or SPLIT of the
corresponding table partition):
It tries to assign it the same name as the corresponding table partition. If that
fails, it generates a name with the form SYS_Pnnn (see "Partition and
Subpartition Names"). You can rename the partition later.
For ADD PARTITION, Oracle creates a segment with the default physical
storage attributes of the base index. If a tablespace other than DEFAULT
(which causes local index partitions to be co-located with corresponding base
table partitions) has been specified for the parent index, the index partition is
placed in that tablespace. Otherwise, the tablespace in which the new index
partition resides is that of the corresponding partition of the underlying table.
You can modify these attributes later. (The only way to modify TABLESPACE
is to rebuild.)

For SPLIT PARTITION, attributes of the index partition being split are used for
the index partitions resulting from the split. Partition names are the exception,
although Oracle reuses table partition names when possible. For example, for a
table partition with name TP and a local index with name IP, if TP is split into
TP and TP1, then the names of the local index partitions are IP and TP1 (or a
system generated name if TP1 is already in use for that index). If TP is split into
TP1 and TP2, then the local index partitions are TP1 and TP2. That is, if the
table partition name is reused, Oracle tries to reuse the local index partition
name also. All other attributes, however, are inherited from the index partition
being split.
Rather than dropping a local index partition explicitly (for example, before loading
data into its corresponding table partition), you can EXCHANGE the table partition
into a nonpartitioned table, drop the index on that table and perform your load
operation, then create the index and EXCHANGE the table back into the partition
using the INCLUDING INDEXES option.
Global Partitioned Indexes

The DBA is responsible for maintaining the partitioning of a global index. You can
drop or split a partition in a global index. However, you cannot add a partition to a
global index because the high partition of a global index always has a partition bound
of MAXVALUE. See "Management of Global Partitioned Indexes" for more
information on managing global indexes.
Rebuild Index Partition

The ALTER INDEX REBUILD PARTITION statement can be used to regenerate a


single partition in a local or global partitioned index. This saves you from having to
perform DROP INDEX and then CREATE INDEX, which would affect all partitions
in the index.
ALTER INDEX REBUILD PARTITION has four important applications:
To recluster an index partition to recover space and improve performance.
To repair an index partition in case of a media failure on the volume where the
index partition resides or a software corruption of the segment containing the
index partition.
To regenerate a local index partition after loading the underlying table partition
with Import or SQL*Loader. These utilities offer a performance option to

bypass index maintenance, mark the affected index partitions INDEX


UNUSABLE, and let the DBA rebuild them later. (INDEX UNUSABLE is
explained in the next section.) In other words, the strategy of "drop index then
re-create index" can be replaced by a strategy of "mark index partition
UNUSABLE then rebuild index partition."
To rebuild index partitions rendered UNUSABLE by partition maintenance
operations on the underlying table.
INDEX UNUSABLE Attribute

Some maintenance operations mark indexes INDEX UNUSABLE (IU). INDEX


UNUSABLE is an attribute of a nonpartitioned index and of a partition in a
partitioned index. When an index or index partition is marked IU, you get an error if
you try to execute a SELECT or DML statement that requires the index (or partition).
When a single index partition is marked IU, you must rebuild the partition to make it
valid again before using it. However, while one partition is marked IU the other
partitions of the index are valid and you can execute SELECT or DML statements that
require the index as long as the statements do not access the IU partition.
You can also split or rename the IU partition before rebuilding it, and you can drop an
IU partition of a GLOBAL index.
When a nonpartitioned index is marked IU, you can drop the index. You can also drop
an IU partition of a GLOBAL index.x and re-create it, and you can use ALTER
INDEX REBUILD to rebuild a nonpartitioned index.
Six types of maintenance operations can mark index partitions INDEX UNUSABLE.
In all cases, you must rebuild the index partitions when the operation is complete.
Operations like Import Partition or conventional path SQL*Loader that offer an
option to bypass local index maintenance. When the Import is complete, the
affected local index partitions are marked IU.
Direct path SQL*Loader leaves affected local index partitions and global
indexes in an IU state if the index is out of date with respect to the data that it
indexes. (INDEX UNUSABLE was previously known as Direct Load State.)
The index can be out of date for the following reasons:
o The index could not be maintained by the load due to a space
management error (for example, out of extents).

o The user requested the SKIP_INDEX_MAINTENANCE option.


Partition maintenance operations like ALTER TABLE MOVE PARTITION that
change rowids. These operations mark the affected local index partition and all
global index partitions IU.
Partition maintenance operations like ALTER TABLE TRUNCATE
PARTITION or DROP PARTITION that remove rows from the table. These
operations mark the affected local index partition and all global index partitions
IU.
Partition maintenance operations like ALTER TABLE SPLIT PARTITION that
modify the partition definition of local indexes but do not automatically rebuild
the index data to match the new definitions. These operations mark the affected
local index partition(s) IU. (ALTER TABLE SPLIT PARTITION also marks all
global index partitions IU because it results in changes to rowids.)
Index maintenance operations like ALTER INDEX SPLIT PARTITION that
modify the partitioning definition of the index but do not automatically rebuild
the affected partitions. These operations mark the affected index partition(s) IU.
However, if you split a USABLE partition of a global index, resulting partitions
are created USABLE. If the partition which was split was marked IU, then so
are the partitions resulting from the split. (Note that dropping a partition of a
global index which is either IU or is not empty causes the next partition of the
index to become IU.)
Privileges for Partitioned Tables and Indexes
Privileges for partitions are granted on the parent table or index, not on individual
partitions. If you want to grant access to a table on a per-partition basis, you can
define a view on a partition of a table and then grant privileges on that view
(see "Viewing Partitions or Subpartitions as Tables").
If a user or role has the privileges required to perform an Oracle operation on
nonpartitioned tables and indexes (including the necessary resource privileges), then
the same Oracle operations are allowed on partitioned tables and indexes. For
example:
If you can create nonpartitioned tables, then you can create partitioned tables.
If you can drop nonpartitioned indexes, then you can drop partitioned indexes.

If you can add a column via ALTER to nonpartitioned tables, then you can add
a column via ALTER to partitioned tables.
If a user or role has the privileges required to perform an ALTER operation on a table
or index, then the ALTER operations on partitions of the table or index can be
invoked, with some exceptions.
Additional Information:
See Oracle8i SQL Reference for information about privileges for the ALTER
TABLE and ALTER INDEX commands.

Auditing for Partitioned Tables and Indexes


All of the ALTER TABLE PARTITION operations are audited just like ALTER
TABLE operations. No additional audit attributes are used for partitions.

Partition-Extended and Subpartition-Extended Table


Names
You can perform bulk operations at the partition or subpartition level; that is, bulk
operations can be restricted to just the rows of a particular partition or subpartition.
For example, if you want to drop a partition without making all the global indexes
UNUSABLE, you would want to delete all the rows from just that partition.
Such operations are very naturally expressed with a SQL extension that provides
syntax for partition-extended table names and subpartition-extended table names.
Trying to phrase the same operations with a WHERE clause predicate is often
cumbersome, especially when a range partitioning key uses multiple columns.
PARTITION and SUBPARTITION Specifications
The table specification syntax for the following DML statements can contain an
optional PARTITION specification for partitioned tables, or an optional PARTITION
or SUBPARTITION specification for composite-partitioned tables:
SELECT

INSERT
UPDATE
DELETE
LOCK TABLE
For example:
SELECT * FROM schema.table PARTITION part_name;

For a composite-partitioned table, using the PARTITION specification restricts the


operation to data contained in all subpartitions of the specified partition.
Additional Information:
See Oracle8i SQL Reference for information about the syntax of DML
statements.

Viewing Partitions or Subpartitions as Tables


The PARTITION or SUBPARTITION syntax for table specifications provides a
simple way of viewing individual partitions or subpartitions as tables: You can use the
partition-extended table name or subpartition-extended table name to create a view
that selects from just one partition or subpartition, and this view can then be used in
place of a table. For example:
CREATE VIEW sales_feb98_v1 AS
SELECT * FROM sales SUBPARTITION (feb98_s1);
SELECT * FROM sales_feb98_v1;

With such views you can also build partition-level or subpartition-level access control
mechanisms by granting (revoking) privileges on these views to (from) other users or
roles.
Note:

For application portability and ANSI syntax compliance, you should always
use views to insulate your applications from this Oracle proprietary
extension.

Using Partition- and Subpartition-Extended Table Names


This section describes restrictions on the use of the PARTITION and
SUBPARTITION options in table specifications, and provides examples of SQL
statements that include the PARTITION or SUBPARTITION option.
Restrictions on Partition- and Subpartition-Extended Table Names

The use of partition- and subpartition-extended table names has the following
restrictions:
1 A partition- or subpartition-extended table name cannot refer to a remote
schema object.
A partition- or subpartition-extended table name cannot contain a database link
or a synonym which translates to a table with a database link. If you need to use
remote partitions or subpartitions, you can create a view at the remote site
which uses the partition- or subpartition-extended table name syntax and refer
to that remote view.
1 The partition- or subpartition-extended table name syntax is not supported by
PL/SQL.
A SQL statement that has the partition- or subpartition-extended table name
syntax cannot be used in a PL/SQL block, although it can be used through
dynamic SQL with the DBMS_SQL package. If you need to refer to a partition
or subpartition within a PL/SQL block, you can use views which in turn use the
partition- or subpartition-extended table name syntax.
1 Only base tables are allowed.
A partition or subpartition extension must be specified with a base table. No
synonyms, views, or any other schema objects are allowed.

Examples of Using the PARTITION Specification

The following statements contain valid partition-extended table names:


SELECT * FROM sales PARTITION (nov97) s
WHERE s.amount_of_sale > 1000;
UPDATE sales PARTITION (feb98) s
SET s.account_name = UPPER(s.account_name);
DELETE FROM sales PARTITION (nov97)
WHERE amount_of_sale != 0;
INSERT INTO sales PARTITION (oct97)
SELECT * FROM lastest_data;
INSERT INTO sales PARTITION (oct97)
VALUES (...);
INSERT INTO sales PARTITION (oct97)
(acct_no, ..., week_no)
VALUES (...);
LOCK TABLE sales PARTITION (jun98) IN EXCLUSIVE MODE;
CREATE VIEW sales_feb98 AS
SELECT * FROM sales PARTITION (feb98);

Examples of Using the SUBPARTITION Specification

The following statements contain valid subpartition-extended table names:


SELECT * FROM sales SUBPARTITION (nov97_s1) s
WHERE s.amount_of_sale > 1000;
UPDATE sales SUBPARTITION (feb98_s4) s
SET s.account_name = UPPER(s.account_name);
DELETE FROM sales SUBPARTITION (nov97_s3)
WHERE amount_of_sale != 0;
INSERT INTO sales SUBPARTITION (oct97_s5)
SELECT * FROM lastest_data;
INSERT INTO sales SUBPARTITION (oct97_s2)
VALUES (...);
INSERT INTO sales SUBPARTITION (oct97_s4)
(acct_no, ..., week_no)
VALUES (...);
LOCK TABLE sales SUBPARTITION (jun98_s1) IN EXCLUSIVE MODE;
CREATE VIEW sales_feb98_1 AS

Got

SELECT * FROM sales SUBPARTITION (feb98_s1);

KEE
dep
12c

12c
Ava
Prev

Copyright 1999 Oracle Corporation.


All Rights Reserved.

Next

Fre
Rep

BEW
11g
Got

Partitioning an Oracle table Tips


Oracle Database Tips by Burleson Consulting
January 24, 2015

Search BC Oracle
Sites

Search
Home
E-mail Us
Oracle Articles
New Oracle Articles

Oracle Training

Partitioning is a divide-and-conquer approach to improving Oracle


maintenance and SQL performance. Anyone with un-partitioned
databases over 500 gigabytes is courting disaster. Databases become
unmanageable, and serious problems occur:

Files recovery takes days, not minutes

Rebuilding indexes (important to re-claim space and improve


performance) can take days

Queries with full-table scans take hours to complete

Index range scans become inefficient

Oracle Tips
Oracle Forum
Class Catalog

Remote DBA
Oracle Tuning
Emergency 911
RAC Support
Apps Support

One of the best features in Oracle data warehousing is the ability to


swap-out standard Oracle tables and partitioned tables. Here is the
syntax of the ?exchange partition? command:

Analysis
Design
Implementation

ALTER TABLE <table_name>


EXCHANGE PARTITION <partition_name>
WITH TABLE <new_table_name>

Oracle Support

<including | excluding> INDEXES


<with | without> VALIDATION
EXCEPTIONS INTO <schema.table_name>;

SQL Tuning
Security
Oracle UNIX
Oracle Linux
Monitoring
Remote support

Preparing a new table partition is resource intensive and loading the


new data into a staging area relieves and concurrent-user issues
because the staging table is segregated from the ?live? data
warehouse.

Remote plans
Remote services
Application Server
Applications
Oracle Forms
Oracle Portal
App Upgrades
SQL Server
Oracle Concepts
Software Support

Please see related partitioning pages:

Justifying Oracle partitioning


Find latest partition in Oracle table
Oracle partitioning methods

Remote Support
Development
Implementation

oracle partitioning tips


Oracle Partitioning

Consulting Staf

Oracle interval partitioning tips

Consulting Prices
Help Wanted!

Oracle Posters

Oracle Partition Key Statistics & tuning


Once the data is loaded into the staging table, you can build the
indexes, estimate the CBO statistics and use the ?exchange partition?
command to load the table into the production environment with
minimal impact.

Oracle Books
Oracle Scripts
Ion

Part 1: The Basics of Partitioning and How to Partition Tables.

Excel-DB
Don Burleson Blog

Introduction
Oracle DBAs face an ever growing and demanding work environment. The only
thing that may outpace the demands of the work place is the size of the databases
themselves. Database size has grown to a point where they are now measured in
the hundreds of gigabytes, and in some cases, several terabytes. The
characteristics of very large databases (VLDB) demand a different style of
administration. The administration of VLDB often includes the use of partitioning
of tables and indexes.

Since partitioning is such an integral part of VLDB the remainder of this article
will focus on how to partition, specifically, the partitioning of tables in an Oracle
9i Release 2 environment. Part 2 of this article will focus on the partitioning of
indexes. The complete article will cover:

Partitioning Defined

When To Partition

Different Methods Of Partitioning

Partitioning Of Tables

Partitioning Of Indexes

The organization of this article is modular so you can skip to a specific topic of
interest. Each of the table partitioning methods (Range, Hash, List, Range-Hash
and Range-List) will have its own section that includes code examples and check
scripts.
Background
This article assumes that Oracle 9i Release 2 is properly installed and running.
You will also need to have a user account that has a minimum of Create Table,
Alter Table and Drop Table privileges. In addition to the basic privileges listed
above, the creation of five small tablespaces (TS01, TS02, TS03, TS04, TS05) or
changes to the tablespace clause will need to be done to use the examples
provided in this article.
Ideally, you should try each of the scripts in this article under a DBA role. All
scripts have been tested on Oracle 9i Release 2 (9.2) running on Windows 2000.
Partitioning Defined
The concept of divide and conquer has been around since the times of Sun Tzu
(500 B.C.). Recognizing the wisdom of this concept, Oracle applied it to the
management of large tables and indexes. Oracle has continued to evolve and
refine its partitioning capabilities since its first implementation of range
partitioning in Oracle 8. In Oracle 8i and 9i, Oracle has continued to add both
functionality and new partitioning methods. The current version of Oracle 9i
Release 2 continues this tradition by adding new functionality for list partitioning
and the new range-list partitioning method.

When To Partition
There are two main reasons to use partitioning in a VLDB environment. These
reasons are related to management and performance improvement.
Partitioning offers:

Management at the individual partition level for data loads,


index creation and rebuilding, and backup/recovery. This can
result in less down time because only individual partitions being
actively managed are unavailable.

Increased query performance by selecting only from the relevant


partitions. This weeding out process eliminates the partitions
that do not contain the data needed by the query through a
technique called partition pruning.

The decision about exactly when to use partitioning is rather subjective. Some
general guidelines that Oracle and I suggest are listed below.
Use partitioning:

When a table reaches a "large" size. Large being defined relative to your
environment. Tables greater than 2GB should always be considered for
partitioning.

When performance benefits outweigh the additional


management issues related to partitioning.

When the archiving of data is on a schedule and is repetitive. For


instance, data warehouses usually hold data for a specific
amount of time (rolling window). Old data is then rolled off to be
archived.

Take a moment and evaluate the criteria above to make sure that partitioning is
advantageous for your environment. In larger environments partitioning is worth
the time to investigate and implement.
Different Methods of Partitioning
Oracle 9i, Release 2 has five partitioning methods for tables. They are listed in the
table below with a brief description.

PARTITIONING METHOD

BRIEF DESCRIPTION

Range Partitioning

Used when there are logical ranges of


data. Possible usage: dates, part
numbers, and serial numbers.

Hash Partitioning

Used to spread data evenly over


partitions. Possible usage: data has no
logical groupings.

List Partitioning

Used to list together unrelated data into


partitions. Possible usage: a number of
states list partitioned into a region.

Composite Range-Hash
Partitioning

Used to range partition first, then


spreads data into hash partitions.
Possible usage: range partition by date
of birth then hash partition by name;
store the results into the hash partitions.

Composite Range-List
Partitioning

Used to range partition first, then


spreads data into list partitions. Possible
usage: range partition by date of birth
then list partition by state, then store the
results into the list partitions.

Range Partitioning

Used when there are logical ranges of


data. Possible usage: dates, part
numbers, and serial numbers.

For partitioning of indexes, there are global and local indexes. Global indexes
provide greater flexibility by allowing indexes to be independent of the partition
method used on the table. This allows for the global index to reference different
partitions of a single table. Local indexes (while less flexible than global) are
easier to manage. Local indexes are mapped to a specific partition. This one-toone relationship between local index partitions and table partitions allows Oracle
the ability to manage local indexes. Partitioning of indexes will be the focus of
Part 2 of this article.
Detailed examples and code will be provided for each partitioning method in their
respective sections. The use of the ENABLE ROW MOVEMENT clause is
included in all of the examples of table partitioning to allow row movement if the
partition key is updated.
Partitioning of Tables

Range Partitioning
Range partitioning was the first partitioning method supported by Oracle in Oracle
8. Range partitioning was probably the first partition method because data
normally has some sort of logical range. For example, business transactions can be
partitioned by various versions of date (start date, transaction date, close date, or
date of payment). Range partitioning can also be performed on part numbers,
serial numbers or any other ranges that can be discovered.
The example provided for range partition will be on a table
namedpartition_by_range (what else would I call it?).
The partition_by_range table holds records that contain the simple personnel data
of FIRST_NAME, MIDDLE_INIT, LAST_NAME, BIRTH_MM, BIRTH_DD,
and BIRTH_YYYY. The actual partitioning is on the following columns
BIRTH_YYYY, BIRTH_MM, and BIRTH_DD. The complete DDL for the
PARTITION_BY_RANGE table is provided in the script range_me.sql.
A brief explanation of the code follows. Each partition is assigned to its own
tablespace. The last partition is the "catch all" partition. By using maxvalue the
last partition will contain all the records with values over the second to last
partition.
Hash Partitioning
Oracle's hash partitioning distributes data by applying a proprietary hashing
algorithm to the partition key and then assigning the data to the appropriate
partition. By using hash partitioning, DBAs can partition data that may not have
any logical ranges. Also, DBAs do not have to know anything about the actual
data itself. Oracle handles all of the distribution of data once the partition key is
identified.
The hash_me.sql script is an example of a hash partition table. Please note that the
data may not appear to be distributed evenly because of the limited number of
inserts applied to the table.
A brief explanation of the code follows. The PARTITION BY HASH line is where
the partition key is identified. In this example the partition key is AGE. Once the
hashing algorithm is applied each record is distributed to a partition. Each
partition is specifically assigned to its own tablespace.
List Partitioning
List partitioning was added as a partitioning method in Oracle 9i, Release 1. List

partitioning allows for partitions to reflect real-world groupings (e.g.. business


units and territory regions). List partitioning differs from range partition in that the
groupings in list partitioning are not side-by-side or in a logical range. List
partitioning gives the DBA the ability to group together seemingly unrelated data
into a specific partition.
The list_me.sql script provides an example of a list partition table. Note the last
partition with the DEFAULT value. This DEFAULT value is new in Oracle 9i,
Release 2.
A brief explanation of the code follows. The PARTITION BY LIST line is where
the partition key is identified. In this example, the partition key is STATE. Each
partition is explicitly named, contains a specific grouping of VALUES and is
contained in its own tablespace. The last partition with the DEFAULT is the "catch
all" partition. This catch all partition should be queried periodically to make sure
that proper data is being entered.
Composite Range-Hash Partitioning
Composite range-hash partitioning combines both the ease of range partitioning
and the benefits of hashing for data placement, striping, and parallelism. Rangehash partitioning is slightly harder to implement. But, with the example provided
and a detailed explanation of the code one can easily learn how to use this
powerful partitioning method.
The range_hash_me.sql script provides an example of a composite range-hash
partition table.
A brief explanation of the code follows. The PARTITION BY RANGE clause is
where we shall begin. The partition key is (BIRTH_YYYY, BIRTH_MM,
BIRTH_DD) for the partition. Next, the SUBPARTITION BY HASH clause
indicates what the partition key is for the subpartition (in this case FIRST_NAME,
MIDDLE_INIT, LAST_NAME). A SUBPARTITION TEMPLATE then defines
the subpartition names and their respective tablespace. Subpartitions are
automatically named by Oracle by concatenating the partition name, an
underscore, and the subpartition name from the template. Remember that the total
length of the subpartition name should not be longer than thirty characters
including the underscore.
I suggest that, when you actually try to build a range-hash partition table, you do it
in the following steps:

Determine the partition key for the range.

Design a range partition table.

Determine the partition key for the hash.

Create the SUBPARTITION BY HASH clause.

Create the SUBPARTITION TEMPLATE.

Do Steps 1 and 2 first. Then you can insert the code created in Steps 3 -5 in the
range partition table syntax.
Composite Range-List Partitioning
Composite range-list partitioning combines both the ease of range partitioning and
the benefits of list partitioning at the subpartition level. Like range-hash
partitioning, range-list partitioning needs to be carefully designed. The time used
to properly design a range-list partition table pays off during the actual creation of
the table.
The range_list_me.sql script provides an example of a composite range-list
partition table.
A brief explanation of the code follows. The PARTITION BY RANGE clause
identifies the partition key (BIRTH_YYYY, BIRTH_MM, BIRTH_DD). A
SUBPARTITION TEMPLATE then defines the subpartition names and their
respective tablespace. Subpartitions are automatically named by Oracle by
concatenating the partition name, an underscore, and the subpartition name from
the template. Remember that the total length of the subpartition name should not
be longer than thirty characters including the underscore.
When building a range-list partition table you may want to refer to the steps
mentioned at the end of the Composite Range-List section. The only difference is
in Step 4. Instead of "Create the SUBPARTITION BY HASH clause" it would
read, "Create the SUBPARTITION BY LIST clause" for the range-list partition
table.
Part 2: Partitioning of Indexes
In Part 1 of "Partitioning in Oracle 9i Release 2," we learned how to use the
various table partitioning methods in the latest release of Oracle. We will now
continue on and learn about Globally Partitioned and Locally Partitioned Indexes.

We will cover:

Background/Overview

Globally Partitioned Indexes

Locally Partitioned Indexes

When To Use Which Partitioning Method

Real-Life Example

Background

This article assumes that Oracle 9i Release 2 is properly installed and running.
You will also need to have a user account that has a minimum of Create Index,
Alter Index and Drop Index privileges. In addition to the basic privileges listed
above, the creation of five small tablespaces (ITS01, ITS02, ITS03, ITS04, ITS05)
or changes to the tablespace clause will need to be done to use the examples
provided in this article.
Ideally, you should try each of the scripts in this article under a DBA role. All
scripts have been tested on Oracle 9i Release 2 (9.2) running on Windows 2000.
The examples below build off of the examples that were used in Part 1 of this
article.
Globally Partitioned Indexes

There are two types of global indexes, non-partitioned and partitioned. Global
non-partitioned indexes are those that are commonly used in OLTP databases
(refer to Figure1). The syntax for a globally non-partitioned index is the exactly
same syntax used for a "regular" index on a non-partitioned table. Refer
to gnpi_me.sql (http://www.dbazine.com/code/GNPI_ME.SQL) for an example of
a global non-partitioned index.

Figure 1

The other type of global index is the one that is partitioned. Globally partitioned
indexes at this time can only be ranged partitioned and has similar syntactical
structure to that of a range-partitioned
table. gpi_me.sql(http://www.dbazine.com/code/GPI_ME.SQL) is provides for an
example of a globally partitioned index. Note that a globally partitioned index can
be applied to any type of partitioned table. Each partition of the globally
partitioned index can and may refer to one or more partitions at the table level. For
a visual representation of a global partitioned index refer to Figure 2.

Figure 2

The maintenance on globally partitioned indexes is a little bit more involved


compared to the maintenance on locally partitioned indexes. Global indexes need
to be rebuilt when there is DDL activity on the underlying table. The reason why
they must be rebuilt is that DDL activity often causes the global indexes to be
usually marked as UNUSABLE. To correct this problem there are two options to
choose from:

Use ALTER INDEX <index_name> REBUILD; or

Use UPDATE GLOBAL INDEX clause when using ALTER TABLE.

The syntax for the ALTER INDEX statement is relatively straightforward so we


will only focus on the UPDATE GLOBAL INDEX clause of the ALTER TABLE
statement. The UPDATE GLOBAL INDEX is between the partition specification
and the parallel clause. The partition specification can be any of the following:

ADD PARTITION | SUBPARTITION (hash only)

COALESCE PARTITION | SUBPARTITION

DROP PARTITION

EXCHANGE PARTITION | SUBPARTITION

MERGE PARTITION

MOVE PARTITION | SUBPARTITION

SPLIT PARTITION

TRUNCATE PARTITION | SUBPARTITION

For example:

ALTER TABLE <TABLE_NAME>


<PARTITION SPECIFICATION>
UPDATE GLOBAL INDEX
PARALLEL (DEGREE #)

Locally Partitioned Indexes

Locally partitioned indexes are for the most part very straightforward.
The lpi_me.sql (http://www.dbazine.com/code/LPI_ME.SQL) script shows
examples of this type of index. In the script, locally partitioned indexes are created
on three differently partitioned tables (range, hash, and list). Figure 3 gives a
visual representation of how a locally partitioned index works.

Figure 3

Extra time should be allocated when creating locally partitioned indexes on rangehash or range-list partitioned tables. There are a couple reasons that extra time is
needed for this type of index. One of the reasons is a decision needs to be made on
what the index will be referencing in regards to a range-hash or range-list
partitioned tables. A locally partitioned index can be created to point to either
partition level or subpartition level.
Script lpi4cpt1_me.sql (http://www.dbazine.com/code/LPI4CPT1_ME.SQL) is the
example for the creation of two locally partitioned indexes. This scripts show how
to create a locally partitioned index on both a range-hash and range-list partitioned
tables at the partition level. Each of the partitions of the locally partitioned indexes
is assigned to its own tablespace for improved performance.
When creating a locally partitioned index one needs to keep in mind the number

of subpartitions of the range-hash or range-list partitioned table being indexed.


Reason being, is that the locally partitioned index will need to reference each
subpartition of the range-hash or range-list partitioned table. So, for the locally
partitioned index created by lpi4cpt2.me.sql , this means that one index references
twenty-five different subpartitions. For a visual representation of this refer to
Figure 4. Script is provided as an example of locally partitioned index on a rangelist partition table.

Figure 4

Note: At this time Oracle has not implemented a SUBPARTITION TEMPLATE


clause for the creation of locally partitioned indexes on range-hash or range-list
partition tables. This means that you need to type everything out as in the
examples in lpi4cpt2_me.sql and lpi4cpt3_me.sql.
Maintenance of locally partitioned indexes is much easier than the maintenance of
globally partitioned indexes. Whenever there is DDL activity on the underlying
indexed table Oracle rebuilds the locally partitioned index.
This automatic rebuilding of locally partitioned indexes is one reason why most
DBAs prefer locally partitioned indexes.

When to Use Which Partitioning Method

There are five different table partitioning methods (range, hash, list, range-hash
and range-list) and three for indexes (global non-partitioned, global partitioned
and locally partitioned). So, the obvious question is: "When do I use which
combination of table and index partitioning?" There is no concrete answer for that
question. However, here are some general guidelines on mixing and matching
table and index partitioning.

First determine if you need to partition the table.


o

Next decide which table partitioning method is right for your


situation.
o

Each method is described in Part 1 of this article under


"Different Methods of Partitioning"

Determine how volatile the data is.


o

Refer to Part 1 of this article under "When To Partition"

How often are there inserts, updates and deletes?

Choose your indexing strategy: global or local partitioned


indexes.
o

Each type has its own maintenance consideration.

These guidelines are good place to start when developing a partitioning solution.
Real Life Example

The "rolling window" concept of only retaining a certain amount of data is the
norm in most data warehousing environments. This rolling window can also used
to archive data from an OLTP system. For our example we will assume that there
is a twelve month rolling window.
Our example will cover the following steps:

Create a range partition table that has a locally partitioned


index.

Use "CREATE TABLE . . AS" to copy the data into a separate


table.

Archive off the table created to hold the rolled off data.

Drop last month partition.

Add new months partition.

Script example.sql is an annotated code of the example above.


Part 3: Partitioning in Oracle 10g and Oracle 11g
New in Oracle 10g
Each version release of Oracle comes with its own exciting set of new features.
The following is a list of some partitioning features for Oracle 10g:
Improvements for VLDB such as data warehouses. These users depend on
partitioned tables.

Maximum number of partitions per object: This has been


increased from 64K-1 to 1024K-1. This increase in the maximum
number of partitions allowed creates much higher flexibility with
regard to granularity of partitioned objects as well as creating
many more partitioning approaches for each user to consider.

Enhanced Dynamic Partition Pruning: For VLDB's, this


feature enhances partition pruning for complex queries. For
some, this can provide enhanced performance for a more robust
set of complex queries.

Resource Optimized DROP TABLE for Partitioned


Tables: When using PURGE mode to drop large partitioned
tables, the result is a large number of partions that have to be
removed from the system logically. During the DROP operation,
the large partitioned table is internally split to drop chunks of
partitions. This new feature gives the capability of transparently
dropping such an object in an incremental fashion. This can help
with run-times and help optimize resource consumption.

Partition Change Tracking Refresh Without Materialized


View Logs:With this feature, Partition Change Tracking Refresh
(PCT) does not require materialized view logs. Combining PCT
with a fast refresh enables a refresh where one table is using
PCT and the other is using materialized view logs. This can be a
faster refresh, and now materialized views can be used without
the overhead of materialized view logs.

Not just VLDBs benefitted with the release of Oracle 10g. Partionining on indexes

also got a hand up:

Online Indexing for Local Partitioned Index: This feature


allows online indexing for local partitioned indexes. This means it
is now possible to create an index on a partition while updating
it. This also holds true with with unpartitioned indexes.

Fast Partition Split for Partitioned Index Organized


Tables: This feature enhances the SPLIT command. Historically,
the SPLIT command moved each of the rows from an existing
partition into one of the two new partitions following the split of
a single partition of an index organized table into two new
partitions. The performance enhancement here is that rows do
not have to be moved if all of the rows in the existing partition
fall into one of the new partitions.

It is possible to ADD, MERGE and SPLIT table partitions in a version-enabled


table through the use of the alter_option parameter with the AlterVersionedTable
procedure.
New in Oracle 11g

REF partitioning: The 11g REF partitioning allows you to


partition a table based on the values of columns within other
tables. Source: Mark Rittman

Partitioning: Partitioning by logical object and automated


partition creation.

New Oracle11g Advisors - New 11g Oracle Streams


Performance Advisor and Partitioning Advisor. Source: Mark
Rittman

Interval Partitioning - Robert Freeman notes that 11g "interval


Partitioning makes it easier to manage partitions":

"Wouldn't it be nice if you could just tell Oracle you wanted to partition
every month and it would create the partitions for you? That is exactly
what interval partitioning does."
"This is a new 11g partitioning scheme that automatically creates timebased partitions as new data is added." Source: Mark Rittman
"This is a marvelous one ! You can now partition by date, one partition
per month for example, with automatic partition
creation."Source: Laurent Schneider

Here is an example:
create table selling_stuff_daily
( prod_id number not null, cust_id number not null
, sale_dt date not null, qty_sold number(3) not null
, unit_sale_pr number(10,2) not null
, total_sale_pr number(10,2) not null
, total_disc number(10,2) not null)
partition by range (sale_dt)
interval (numtoyminterval(1,'MONTH'))
( partition p_before_1_jan_2007 values
less than (to_date('01-01-2007','dd-mm-yyyy')));

Note the interval keyword. This defines the interval that you want each
partition to represent. In this case, Oracle will create the next partition
for dates less than 02-01-2007 when the first record that belongs in
that partition is created."

Improved SQL Access Advisor - The 11g SQL Access Advisor


gives partitioning advice, including advice on the new interval
partitioning. Interval partitioning is an automated version of
range partitioning, where new equally-sized partitions are
automatically created when needed. Both range and interval
partitions can exist for a single table, and range partitioned
tables can be converted to interval partitioned tables.

Get the Complete


Oracle SQL Tuning Information
The landmark book "Advanced Oracle SQL
Tuning The Definitive Reference" is filled with
valuable information on Oracle SQL Tuning. This
book includes scripts and tools to hypercharge
Oracle 11g performance and you can buy it for
30% off directly from the publisher.

Burleson is the American Team

Note: This Oracle documentation was created as a support and Oracle


training reference for use by our DBA performance tuning consulting
professionals. Feel free to ask questions on our Oracle forum.
Verify experience! Anyone considering using the services of an Oracle

support expert should independently investigate their credentials and


experience, and not rely on advertisements and self-proclaimed expertise. All
legitimate Oracle experts publish their Oracle qualifications.
Errata? Oracle technology is changing and we strive to update our BC
Oracle support information. If you find an error or have a suggestion for
improving our content, we would appreciate your feedback. Just email:
and include the URL for the page.

Burleson Consulting
The Oracle of Database Support
Oracle Performance Tuning

Remote DBA Services

Copyright 1996 - 2016


All rights reserved by Burleson
Oracle is the registered trademark of Oracle Corporation.

DATAWAREH
OUSE
CONCEPTS
A blog where you can explore everything about
Datawarehouse,OBIEE,Informatica,Hadoop,Oracle SQL-PLSQL,Cognos and
much more....

HOME
OBIEE
INFORMATICA
SQL
INFORMATICA SCENARIOS
HADOOP
CLOUD COMPUTING
UNIX
DATASTAGE
ORACLE
TERADATA
COGNOS
SAS
BO
BIG DATA

Tuesday, 14 August 2012

What is a PARTITION in Oracle?Why to use Partition


And Types of Partitions
PARTITIONS

Partitioning allows tables, indexes, and index-organized tables to be subdivided


into smaller pieces, enabling these database objects to be managed and
accessed at a finer level of granularity.

When to Partition a Table??

Tables greater than 2 GB should always be considered as candidates for


partitioning.

Tables containing historical data, in which new data is added into the
newest partition. A typical example is a historical table where only the current
month's data is updatable and the other 11 months are read only.

When the contents of a table need to be distributed across different types


of storage devices.
TYPES

1 Range partitions
2 List partitions
3 Hash partitions
4 Sub partitions

ADVANTAGES OF PARTITIONS

Reducing downtime for scheduled maintenance, which allows


maintenance operations to be carried out on selected partitions while other
partitions are available to users.

Reducing downtime due to data failure, failure of a particular partition will


no way affect other partitions.

Partition independence allows for concurrent use of the various partitions


for various purposes.
What is the advantage of partitions, by storing them in different Tablespaces??

1 Reduces the possibility of data corruption in multiple partitions.


2 Back up and recovery of each partition can be done independently.

Partitioning Key
Each row in a partitioned table is unambiguously assigned to a single partition.
The partitioning key is comprised of one or more columns that determine the
partition where each row will be stored

1.RANGE PARTITIONS

Definition: A table that is partitioned by range is partitioned in such a way that


each partition contains rows for which the partitioning expression value lies
within a given range.
Creating range partitioned table
SQL> Create table Employee(emp_no number(2),emp_name varchar(2)) partition
by range(emp_no) (partition p1 values less than(100), partition p2 values less
than(200), partition p3 values less than(300),partition p4 values less
than(maxvalue));
Inserting records into range partitioned table
SQL> Insert into Employee values(101,a);

-- this will go to p1

SQL> Insert into Employee values(201,b);

-- this will go to p2

SQL> Insert into Employee values(301,c);

-- this will go to p3

SQL> Insert into Employee values(401,d);

-- this will go to p4

Selecting records from range partitioned table

SQL> Select *from Employee;


SQL> Select *from Employee partition(p1);
Adding a partition
SQL> Alter table Employee add partition p5 values less than(400);
Dropping a partition
SQL> Alter table Employee drop partition p1;
Renaming a partition
SQL> Alter table Employee rename partition p3 to p6;
Truncate a partition
SQL> Alter table Employee truncate partition p5;
Splitting a partition
SQL> Alter table Employee split partition p2 at(120) into (partition p21,partition
p22);
Exchanging a partition
SQL> Alter table Employee exchange partition p2 with table Employee_x;
Moving a partition
SQL> Alter table Employee move partition p21 tablespace ABC_TBS;

2. LIST PARTITIONS

Definition: List partitioning enables you to explicitly control how rows map to
partitions by specifying a list of discrete values for the partitioning key in the
description for each partition.
Creating list partitioned table
SQL> Create table Employee (Emp_no number(2),Emp_name varchar(2)) partition
by list(Emp_no) (partition p1 values(1,2,3,4,5), partition p2
values(6,7,8,9,10),partition p3
values(11,12,13,14,15), partition p4
values(16,17,18,19,20));
Inserting records into list partitioned table
SQL> Insert into Employee values(4,xxx);

-- this will go to p1

SQL> Insert into Employee values(8,yyy);

-- this will go to p2

SQL> Insert into Employee values(14,zzz);

-- this will go to p3

SQL> Insert into Employee values(19,bbb); -- this will go to p4


Selecting records from list partitioned table
SQL> Select *from Employee;
SQL> Select *from Employee partition(p1);
Adding a partition
SQL> Alter table Employee add partition p5 values(21,22,23,24,25);
Dropping a partition
SQL> Alter table Employee drop partition p5;
Renaming a partition
SQL> Alter table Employee rename partition p5to p1;
Truncate a partition
SQL> Alter table Employee truncate partition p5;
Exchanging a partition
SQL> Alter table Employee exchange partition p1 with table Employee_x;
Moving a partition
SQL> Alter table Employee move partition p2 tablespace ABC_TBS;

3. HASH PARTITIONS

Definition:Hash partitioning maps data to partitions based on a hashing


algorithm that Oracle applies to the partitioning key that you identify.
Creating hash partitioned table
SQL> Create table Employee(emp_no number(2),emp_name varchar(2))
partition by
hash(emp_no) partitions 5;
Here oracle automatically gives partition names like
SYS_P1
SYS_P2
SYS_P3
SYS_P4

SYS_P5

Inserting records into hash partitioned table(based on hash function)


SQL> Insert into Employee values(5,a);
SQL> Insert into Employee values(8,b);
SQL> Insert into Employee values(14,c);
SQL> Insert into Employee values(19,d);
Selecting records from hash partitioned table
SQL> Select *from Employee;
SQL> Select *from Employee partition(SYS_P2);
Adding a partition
SQL> Alter table Employee add partition p9;
Renaming a partition
SQL> Alter table Employee rename partition p9 to p10;
Truncate a partition
SQL> Alter table Employee truncate partition p9;
Exchanging a partition
SQL> Alter table Employee exchange partition SYS_P1 with table Employee_X;
Moving a partition
SQL> Alter table Employee move partition SYS_P1 tablespace ABC_TBS;
You might also like:

Update and Delete in Correlated Sub query

GROUPING Function In Oracle

Decode Function in Oracle

Linkwithin

9341

10

29

0Google +0

8StumbleUpon0Tumblr2Reddit1Digg0Delicious1

at 14:24:00
Labels: Datawarehouse, Index, Oracle, Partition, SQL

19 comments:
1.

dgm22 February 2013 at 01:33

Good Article
Reply
Replies
1.

DWHLAUREATE7 March 2013 at 22:47

Thankyou @ dgm
Reply
2.

syed hassan khalique17 April 2013 at 12:06

thnx
stay bless. .

for

such

Reply
3.

Anonymous11 July 2013 at 19:21

gr8

doc..

Great

post!

Many

thanks!

Just one question: haven't you forgotten option 4, subpartitions? It is not explained.
Kind regards.
Reply
4.

Junaid Kotwal21 November 2013 at 11:33

Option No. 04 is missing...?


Reply
5.

Junaid Kotwal21 November 2013 at 12:12

One problem is that, You defined in Range Partition when you are creating table and you
create column emp_no number(2). But when you insert data in that table you are
inserting 3 digits in that particular column 'emp_no number(2)'
Reply
6.

Anonymous23 December 2013 at 11:48

Corrected

Example

Insert
into
tango
values(101,'a');-this
Insert
into
tango
values(201,'b');
-this
Insert
into
tango
values(301,'c');-this
Insert into tango values(401,'d'); -- this will go to p4
Reply
Replies

Range
will
will
will

Partition
go
go
go

to
to
to

p2
p3
p4

1.

Anonymous20 July 2014 at 10:28

Good catch :)
Reply
7.

Anonymous15 February 2014 at 20:13

Anonymous(before me) said it correct; still the data type needs to be changed above for
Emp_no column to 3 digits
Reply
8.

Anonymous15 May 2014 at 13:48

Very
Thanks.

precise

Reply
9.

Anonymous13 April 2015 at 13:33

Very Gud Article


Reply
10.

article..

Anonymous8 July 2015 at 07:46

bale bale
Reply
11.

Unknown19 February 2016 at 20:44

type 4 is missing please add


Reply
12.

sutapa bose19 February 2016 at 20:44

type 4 is missing please add


Reply
13.

sutapa bose19 February 2016 at 20:45

Please add type 4


Reply
14.

Unknown25 March 2016 at 21:02

Good tutorial
Reply

15.

Shivam22 September 2016 at 16:32

For
Range
partition,
I
tried
to
add
new
partition
Alter
table
Employee
add
partition
p5
values
less
than(1000);
I got below error -- (previous transformation was on less than(maxvalue))
14074. 00000 - "partition bound must collate higher than that of the last partition"
Could you please tell how to add a new partition after adding max value partition.
Reply
16.

Unknown28 November 2016 at 17:23

God Bless You..


Reply
17.

Sadashiv Dhulashetti5 December 2016 at 09:02

Good explanation...
Reply
Newer PostOlder PostHome
Subscribe to: Post Comments (Atom)

Search This Blog


Search

Kashinathan
on Google+

Live Traffic
Subscribe To

Posts

Comments

Follow by Email
Submit

Followers
Popular Posts

ORACLE FLASHBACK TECHNOLOGY- USAGE & FEATURES


JOINS IN ORACLE-different joins in oracle with examples
How to Unlock the Locked Table in ORACLE
SCD Type 1, SCD Type 2, SCD Type 3,Slowly Changing Dimension
Types,Advantages & Disadvantages
How to assign values for workflow variables in Informatica
What is a FACTLESS FACT TABLE?Where we use Factless Fact
Physical Design and Logical Design in Datawarehouse
IBM Cognos Metric Designer
What is a PARTITION in Oracle?Why to use Partition And Types of Partitions
Types of Lookup Caches in Informatica

JOIN OUR EMAIL NEWSLETTER

Subscribe via Email

Enter e

Submit

Most Discussed Post

JOINS IN ORACLE-different joins in oracle with examples

1. The purpose of a join is to combine the data across tables. 2 . A join is actually performed by
the where clause which combi...

Comments Box

MelisaThe expansion of internet and intelligen

punyavathi sivaThank you for your great information on

Aldrich WrightThere are significant differences but ne

joy johnsonGood one

UnknownGood one to understand for beginners.!!

widget by MS Design

Blog Archive

2016 (13)

o
o
o
o
o

2015 (8)
2014 (22)
2013 (104)
2012 (397)
December (32)
November (72)
October (67)
September (90)
August (107)
Latest Transformations In Informatica
Extracting and Loading Mechanism in DAC
DAC Process Cycle
Components of DAC
Why to use DAC?
HTTP Transformation In Informatica
Null Values in Aggregate Functions
List of Popular Reporting tools in Market
List of Popular ETL Tools in Market

Different Components of the Aggregator Transformat...


How to improve the performance of an Aggregator tr...
UNIQUE CONSTRAINT VIOLATION IN INFORMATICA
Differences between Datawarehouse schema and RDBMS...
Transaction Control Transformation in Informatica
What is Check In and Check Out in Informatica?
Data driven Sessions in Informatica
Dimensions and Measures in Datawarehouse
Oracle Data Integrator Studio-Topology Navigator
ODI - Oracle Data Integrator Repository
How to move mappings from Development folder to Pr...
How to Restart the Informatica Repository Service-...
How to Start Integration Services in Informatica-O...
How to Uninstall Informatica 8.6.1?
Sorting in Informatica
Server Instances in an OBIEE?
How to Rename My Dashboard in OBIEE?
Conformed Dimension in Obiee
Physical Design and Logical Design in Datawarehous...
What is Oracle BI Server?
What is Oracle BI Admin Tool/Oracle Business Intel...
What is Oracle BI Answers?
What is Oracle BI Interactive Dashboards?
What is Oracle BI Delivers?
What is Oracle BI Disconnected Analytics?
What is Oracle BI Publisher?
What is Oracle BI Briefing Books?
What is Oracle BI Office Plug-In?
What is Hyperion Web Analysis?
What is Hyperion SQR Production Reporting?
What is Hyperion Interactive Reporting?
What is Hyperion Financial Reporting?
Why to use OBIA?
What are the Advantages of OBIA
Difference Between OBIEE AND Oracle BI Application...
What is OBIEE,Oracle Business Intelligence Enterpr...
Advantages/Benefits/Features of OBIEE,Oracle Busin...
Components of OBIEE,Oracle Business Intelligence E...
What is Change Data Capture and How to validate CD...

What is Pivoting insert in Oracle?


Clusters in Oracle
How to do Top-N analysis in Oracle
Components of OBIA
Informatic Workflow
Informatica Repository-Repository Server
What is XML Transformation in Informatica
SQL Transformation in Informatica
Data Masking in Informatica
Mapping Analyst for Excel in Informatica 8.6 OBIA
Rank and Dense Rank functions in OBIEE & How to im...
OBIEE 10g Production Installation Steps and Screen...
OBIEE 10g Installation Steps with Screenshots
How to Generate Sequence numbers using Expression ...
What happens when a Foreign Key Join is defined in...
Can we create Subfolder within Parent folder in In...
Compare features in OBIEE 10g and 11g
Plane number to Date conversion in OBIEE
Can we use WITH Clause in Source Qualifier Transfo...
Source Qualifier Query is not working when I run t...
OBIA Data warehouse full load using DAC
What is a PARTITION in Oracle?Why to use Partitio...
How to convert the date field in OBIEE report to a...
What are Global and Local Indexes?
What is ERP -Enterprise Resource Planning or EBS
Different types of Target tables in OBIEE?
How to remove duplicate rows in Informatica
What are EXTERNAL TABLES in Oracle?
What is E business suite?Different kind of EBS tab...
What is EAM in OBIA?
What is OBIA? Oracle BI Applications and various C...
What is index and its use?How to create unique ind...
What is a Role in ORACLE?How to Create and Grant P...
Create,Configure & Schedule iBots or Agents in OBI...
Different Stages of an SQL statement - Optimizer
Data Warehouse Toolkit by Ralph Kimball
What are the different kind of FACT Tables in OBIE...
Building the Data Warehouse-ebook by W.H.Inmon
What is a Date Dimension in OBIEE ?With Examples

Types of Data base triggers? What is a Trigger in ...


Difference between Router and Filter transformatio...
iBots/Agents in OBIEE and How to Manage and Debug ...
Bitmap Indexes in Datawarehousing
Services in OBIEE and OBIEE Services Port number?
What are Sub Queries in ORACLE
JOINS IN ORACLE-different joins in oracle with exa...
DTM-Data Transformation Manager Process
What is the difference between Parameters and Var...
What is a CUBE?Types of Cubes in DWH
Folders in Informatica-Shared folder in Informatic...
What is a FACTLESS FACT TABLE?Where we use Factles...
Informatica Basic Features- Power Centre ,Power Ma...
July (12)
June (17)

o
o
Labels

Initio (1) Agents (10) Aggregator (8)Amazon


Route
53 (1) Amazon's
AWS (1) Apache
AVRO (2) Apache
Hive (4) Assignment
Task (1)Avro (1) B-tree
index (4) bad
file (1) Balanced
hierarchy (1) BI (3) Big
Data (20) Bitmap
Index(3) BO (4) Building
the
Data
Warehouse (5)Business Intelligence (27) Business Intelligence Tools (11) Business Model
and
Mapping
layer (2) Cache
Manager (1) Cassandra(1) Cloud
Computing (8) Cloud
Ab

Dataflow (1)CLOUDERA (1) Cloudera


Impala (1) Cluster (1)Cognos (19) Cognos
10 (15) Conformed
dimension (1) Connected
Lookup (1) CONSTRAINTS(1) Correlated (1) CouchDB (1) Cubes (1) DAAS (1)DAC (8) DATA (2) Data Level
Security (2) Data
Masking (1) Data
Warehouse
Toolkit (1) Database(4) Database

Datawarehouse(233)

partitioning (3) Datamart (2)Datastage (2)


ebook (3)Datawarehouse
OBIA (1) Date

Datawarehouse

Dimension (2) De-serialization (1) Debian

Linux (1) Dimension (6)DNS (1) Dremel (1) DWH (62) Dyn (1) Dynamic
partitioning (1) E-Business
Suite(1) EAM (1) ebook (2) EBS (1) edhat

cache (1) Dynamic


Enterprise

ETL (35)FACEBOOK (2) Fact (9) Factless Fact (1) Fedora Linux (1) Filter
Transformation (3) Functions
in
OBIEE (2) Global
repository (2) Google (2)Google
Big
Query (3) Google Charts (1) Google Cloud (1) Google Cloud Storage (1) Hadoop (21)Hash autokeys (2) Hash
user
keys (2) HBASE (1)Hewlett-Packard's
HP-UX (1) Hierarchy (1) HIVE(3) Hive
QL (2) HTTP (1) Hyperion (5) Hyperion Financial Reporting (1) Hyperion Interactive Reporting (1) Hyperion
SQR
Production
Reporting(1) Hyperion
Web
Linux (1) ELT (1) ERP (1)

Informatica (186)

Analysis (2) IBM (18) iBots(10) IMPALA (1) Index (4) Indexes (4)

In
formatica 9.5 (10) Informatica Interview Questions (1)Informatica Repository Query (1) Informatica

Informatica
Transformations (41)InformaticaScenarios (7) Instanceconfig.xml (1)Integration
Scenario (2)

Services (2) Internet of Things (2)Interview Q and A (1) INVENTORY_ITEM_ID (1)IOT (2) Joiner (2) Key
range (2) Kyle
York (1)Level-Based
Hierarchy (1) linux (1) Local
repository (2) Logical
Dimension (1)LookupTransformation (2) Mac
OS
X (1) Machine
Learning (1) Mapping
Analyst (1) Mappings (5)Massively
parallel
processing (3) Measures (1)Metadata (1) Microsoft

Azure (1) MongoDB (3)MPP (1) MTL_SYSTEM_ITEMS_B (1) Nested


Tables(1) Netflix (1) NetSuite (1) NewSQL (2) NO
transformation (1) NOSQL (3)NQSConfig.INI (1)

10g (129)OBIEE
Installation (4) Object

11.1.1.7 (2)

SQL(3) Normalizer

OBIEE(142) OBIEE
11g (132)OBIEE Errors (3) OBIEE

OBIA (66)

OBIEE
Level

Security (2) OC4J (2) ODI (2) ODI

OLAP (9) OLTP (3) Oracle(86) ORACLE


FLASHBACK
TECHNOLOGY (1)Oracle
10g (30) Oracle
11g (30) ORACLE
APPS (4) Oracle
BI
Admin
Tool (2) Oracle
BI
Repository (1)

Answers (2) ORACLE BI APPS (4) Oracle BI Briefing Books (1) Oracle BI Cluster Controller (1)Oracle BI
Delivers (2) Oracle BI Disconnected Analytics (1) Oracle BI Interactive Dashboards(2) Oracle BI Java
Host (1) Oracle BI Office Plug-In (2) Oracle BI Presentation Server (1) Oracle BI Publisher (2) Oracle BI
Scheduler (2) Oracle BI Server (6) Oracle Collections (1) Oracle Flashback Query (1) ORACLE
PLSQL (2) Palerra (1)Parameters (1) Parent-Child
Hierarchy (2)Partition (1) Pass-through (2) Physical
layer (1) Pig(1) Pivot
tables (1) PLSQL (19) Power
Centre (4)Power
Mart (1) Presentation
layer (1) Presentation
Variable (1) Privileges (1) R (1) Ragged
hierarchy(3) RDBMS (3) READ
ONLY
TABLES (1) Reddit.(1) Redis (1) reject
file (1) Reporting (2)Repository (10) Repository
Modes (2)Repository
services (1) Repository
Variables (1)Request
Variables (1) Reusable
Transformation (1)Riak (1) Role (1) Round-robin (2) Router
Transformation (1) SAP (1) SAP
HANA (1) SAS (8)SCD (4) Sequence
Generator (1) serialization (1)Session
Variables (2) Sessions (6) Skip-level
hierarchy (2) Slowly
Changing
Dimensions (4)Snowflake
Schema (1) Sorted
Input (1) Sorter (2)Source
Qualifier (3) Spark (3) Splice
Machine (1)Splunk (1) SQL (53) SSIS (1) Staging Area (1)Star Schema (1) Static cache (1) Statistical
Analysis(1) Subquery (2) Sun's Solaris (1) Surrogate key(2) Suse Enterprise Linux (1) Teradata (1) Thomas
Kurian (1) Top
N
Analysis (1) Transaction
Control
transformation (1) Transformation (2) Triggers (1)Twitter (1) Ubuntu
Linux (1) Unbalanced
hierarchy(3) Unconnected Lookup (1) Unix (6) update strategy Transformation (1) Varrays (1) Virtual
Column (1) VoltDB (1) Web Server (2) WebLogic Server (1) Workflow Manager (3) Zookeeper (1)

DWHLAUREATE

Counter

COPYRIGHT 2012 DATAWAREHOUSE CONCEPTS. Unauthorized use and/or


duplication of this blog's material without express and written permission
from this blogs author and/or owner is strictly prohibited.
COPYRIGHT 2012 DATAWAREHOUSE CONCEPTS. Simple template. Template images
by andynwt. Powered by Blogger.

Select Language

Translate:

Search

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Home
Java
JVM platform dependent?
Method overriding vs overloading
Why have a private constructor
Difference between object and class
How copy constructors work
Final modifier
Finally block
Java: Will Finally run after return?
Java Protected Example
Java serializable class example
Multiple Inheritance
How to Create a Thread in Java
Interface vs. Abstract Class
Thread States in Java
Arithmetic Exception
Overridden Method
Dynamic Binding
Can constructors be synchronized in Java?
Does Java pass by reference or by value?
Difference between a primitive type and a class type?
Does Java have pointers?
Downcasting in Java
Java: Diamond Problem
Java: Can an interface extend another interface?
Java: Are objects of the same type as the interface implemented?
Java: Can an interface be instantiated?
Find First Nonrepeated Character
Java: Whats the difference between equals() and ==?
Find trailing zeros in factorial

o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Java Reflection Example


Bit Manipulation Interview Questions and Answers
XOR in Java
Java Inner Class Example
When to use inner classes in Java
Inner vs nested class
Java Anonymous Class Example
Anonymous Class Interface
Argument Defined Anonymous Inner Class
C/C++
Introduction
Function Overloading
How to Read Complex C Declarations
C++ abstract keyword
Pure Virtual Function
Lvalues and Rvalues in C
Inline vs. Macro
Diamond Problem
How Vtables Work
Virtual Destructors
Friend Classes in C++
How do you call C functions from C++?
What is a memory leak in C++?
What is the difference between delete and delete[ ]?
Whats the difference between a class variable and an instance variable?
Can static function access non-static members of class?
Execution order of constructor and destructor in inheritance
Does C++ support multiple inheritance?
Can you change the this pointer?
Function Templates in C++ example
C++: The compiler and function templates
C++: Function template with more than one type parameter
C++: #include vs. #include <>
C++: Name Hiding
C++ Ellipsis Catch Handler
What happens if a thrown exception is not handled?
C++ namespace example
C++ const pointer examples
Databases/SQL
SQL Interview Questions
Inner vs. Outer joins
SQL Key Definition
Differences between Primary and Foreign Keys
Natural Key In Database
Secondary Key
Simple key in SQL
Superkey Example
What is Referential Integrity
Having vs. Where clause
How do database indexes work?
What is a self join?
Example of DISTINCT in SQL
Retrieve unique rows without DISTINCT
Practice Interview Question 1
Practice Interview Question 1 continued
Practice Interview Question 1 continued
Practice Interview Question 2
Advanced SQL Interview Questions and Answers

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o

Advanced SQL Interview Questions and Answers Part 2


Practice Interview Question 2 continued
Data Mining vs. Data Warehousing
Ternary/Three-valued Logic in SQL
Find Maximum Value Without Using Aggregate
SQL Injection Example and Tutorial
SQL Injection Prevention
Blind SQL Injection Example
Parameterized Queries vs Prepared Statements
Prepared Statement Example
Difference between a full join and an inner join?
Difference between a left outer join and right outer join?
Difference between a left join and a left outer join?
SQL: Having vs Group By
SQL: Group By with multiple columns
SQL Select Distinct and Order By
SQL Order By default sort order
Derived table vs subquery
Correlated vs Uncorrelated Subquery
Find nth highest salary SQL
Cardinality in SQL
Selectivity in SQL Databases
Cardinality versus Selectivity
Clustered vs. Non Clustered Index
Page versus block
Database Locking
Lock Escalation
Database Deadlock Example
What is a database transaction?
SQL Server Transaction
Oracle Transaction
MySQL Transaction
DB2 Transaction
Concurrent Update Problem
How to Tune Database Performance
Database Full Table Scan
What is cost based optimization?
How to tune SQL queries
SQL Index Performance
What is a bitmap index?
Oracle Indexes Examples
System privileges vs. object privileges
SQL Grant
SQL Revoke
SQL Create User
Database Roles
SQL CASE Statement
SQL Searched CASE Statement
SQL Inline View
RANK() versus DENSE_RANK()
Javascript
Javascript Interview Questions
Javascript Outside the Browser
Javascript: What is ECMAScript?
How to print a Javascript object
Javascript: how var works
Javascript: Block scope
Javascript Function Scope

o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o

o
o
o
o
o
o
o
o

Javascript: Example of Hoisting


What is Javascript minification?
Minification vs Obfuscation
Falsy values in Javascript
Javascript Method Chaining
Javascript Nested Function Example
Javascript Global Object
Wrapper Objects in Javascript
PHP
PHP Interview Questions
Difference between == and === in PHP?
How would you parse HTML in PHP?
PHP: What are magic methods?
PHP: Example of the __autoload function
PHP: self vs $this
PHP: self vs. static
Find if string contains another string php
How to delete an element from an array in php?
PHP toString
Return JSON from PHP
How to remove warnings in PHP?
Advanced PHP Interview Questions And Answers
Advanced PHP Interview Questions And Answers Part 2
Advanced PHP Interview Questions And Answers Part 3
How to return an array from a PHP function
How to delete cookies in PHP
PHP cookie versus session
Can sessions work without cookies?
Data Structures
Data Structure Interview Questions and Answers
Big O Notation
Big O versus Big Omega notations
DFS vs. BFS
Hash Tables versus Binary Search Trees
How to find if a linked list is circular has a cycle or ends
Preorder Traversal Algorithm
Inorder Traversal
Postorder Traversal
Difference between stack and heap
Find nth to last element in a linked list
Delete a node in the middle of a singly linked list
Reverse a linked list
Design Pattern Questions
Design Pattern Interview Questions and Answers
Design Pattern Interview Question 1
Design Pattern Interview Question Part 2
Design Pattern Interview Question part 3
Decorator pattern versus Inheritance
Thread Safety in Singleton
Excel Interview Questions
Excel Interview Questions
Cut and paste versus copy and paste in Excel
How to link cells in Excel
Absolute references in Excel
Excel Range Formula
Excel Entire Column
How to move an entire column in excel?
How to add a dropdown list to Excel


o
o
o
o
o
o
o
o
o
o

o
o
o
o

o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o

HTML5
HTML5 Interview Questions and Answers
History of HTML5
Void elements HTML5
New Features in HTML5 Forms
HTML5 email form field
HTML5 Polyfill Example
What is a shiv in HTML5?
HTML5 Video Codecs
Containers versus codecs
Codec Hardware Support
Networking
Networking Interview Questions
Baud rate vs bit rate
What is a MAC address?
What happens when you visit a website?
Operating Systems
Operating System Interview Questions
How Virtual Memory Works
Paging and Page Faults
Purpose of Swapping
Thread vs. Process
Swapping Versus Paging
Vmware Fusion come with Windows?
Does Parallels Desktop come with Windows?
Monitors vs Semaphores
Example of Threading and Synchronization
User Threads vs. System Threads
Recursion
Recursion Interview Questions
Explanation of Recursion
Can every recursive function be made iterative?
Recursion Versus Iteration
Permutations of A String
Factorial Iterative and Non Recursive
Find nth Fibonacci number
Tail Recursion
Tail Call Optimization
Apache Interview Questions
Introduction
Is a restart to Apache required after a change to .htaccess file?
How to password protect a file in .htaccess
How to disable password protection in .htaccess
How to password protect a directory using .htaccess
Directory directive in .htaccess
Does .htaccess slow site down?
What is an Apache module?
General/Miscellaneous
Introduction
HTML GET vs. POST
Black vs White Box Testing
Postfix vs. Prefix
Is String A Palindrome Function?
CSS id vs. Class
CSS Sprite Example
Recursion Interview Question
Is array access in Java expensive compared to C++?
Java Method Calculate Factorial

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o

o
o

o
o

o
o
o

o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o

Web vs. application server


Why Manhole Covers Are Round
Logarithm in HTML
Exponents in HTML
Less than sign in HTML
Tracking Open Emails
Tracking Opens Plain Text Emails
Click tracking in emails
How To Send an HTML email from Gmail
Network Performance 2 Major Issues
Symmetric vs. Public key Cryptography
Why dont C# and Java support multiple inheritance?
FTP command to transfer a directory
Whats the difference between a compiled and an interpreted language?
Swap numbers without temp
Find Max Without Comparison
Find continuous sequence with largest sum
URL Size Limit
How to find the number of downloads for an app iTunes
How does iTunes rank apps?
How to find your WordPress version
Rank Sets in order of their intersections
Non-Technical Questions
Introduction
Why work here?
Five years?
Why leave?
Interviewing in India
India Introduction
India Recruiters
Working As a Software Engineer
Working life Big Company Part 1
Working life Big Company Part 2
Financial Analyst Questions
Financial Analyst Interview Questions
Financial Analyst interview questions and answers
Financial Analyst interview Questions and Answers Part 2
Job Advice For Programmers
How to prepare for a software engineering interview
Introduction
Should my resume be only one page?
Should I Expect Less Salary After Not Working
Does how I dress matter in an interview?
Does the Company I work for matter?
Should I bring copies of my resume to an interview?
Negotiating an offer for a new job
Puzzles
Cutting a cake into 8 pieces
Puzzles Interview Questions And Answers
Minimum guesses to find a # from 1 to 1000
three-switches-three-bulbs
100 Lockers Puzzle
8 Pennies Find Lightest 7 equal
Measure weight of an elephant with no scale
Measure 4 liters
25 horses 5 tracks 3 fastest puzzle
Same national champion 65 year span
Rope Bridge Puzzle Four People One Flashlight

o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

8 marbles puzzle find heaviest


8 marbles riddle generalize solution
2 Fuses Problem Measure 45 Minutes
Train Escape Puzzle 2 boys
Prisoner Hat Riddle
2 Eggs 100 Floors Puzzle
3 Ants Triangle Puzzle
Find number of squares chessboard
Assortment of Knowledge
Introduction
Web Listings Inc. Scam
WordPress url http error
FTP from Mac Terminal
Mput to FTP from Mac Terminal
Does websense block adsense?
What country are Danish people from?
What country are Dutch people from?
Is Donald Trump a Republican?
Is the Vatican in Rome?
What is a topper?
How does India feed all its people?
Does India give foreign aid?
Does Britain have a space program?
Why is Blackberry also called Crackberry?
Does Google return different results for phones?
Can Google recognize faces?
Can Facebook recognize faces?
Does Google own Yelp?
What countries have Yelp?
Is Yelp in India?
How to make a restricted call from a cell phone?
Is Google auto-complete based on past queries?
Does Yahoo use Bing?
Does Yahoo use Google?
Yahoo Google Antitrust
What share does Mark Zuckerberg own of Facebook?
Who is George Costanza based on?
How to get the radio code for an Acura TSX?
NBA Players that went broke
How much is Zuckerberg worth?
Do airlines x ray checked baggage?
Do airlines charge for infants?
Whats the difference between a nonstop and direct flight?
Do airlines charge for car seats?
Do Airplanes have power outlets?
Do airlines charge for pets?
Do airlines charge for wheelchairs?
Does Prague use the Euro?
Does the Czech Republic use the Euro?
Does Switzerland use the Euro?
How expensive is Switzerland?
How expensive is Paris?
Eiffel Tower Light Show
How much does the Paris Metro cost for one ticket?
Are there roads in Venice?
Are Bank of America debit cards insured?
Is Venice an island?
Review of the Danubius Hotel in London, Regents Park

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Should you use your debit card when traveling?


What is Bank Of Americas international phone number?
What is the cost of a 5 day Oyster card pass in Londons underground tube?
Where is the best place to exchange dollars to pounds in London?
Do they give free tapas in Granada, Spain?
Where is the best place to exchange money in Cordoba, Spain?
Where is the best place to exchange money in Granada, Spain?
Where is the best place to exchange money in Madrid, Spain?
Review of the NH Victoria Hotel in Granada Spain
How to get to Malaga from Granada
How to get to Cordoba from Malaga
Cheapest Airport Shuttle in Honolulu
Cost of taxi Honolulu Airport to Waikiki
How expensive is Honolulu?
Is Terminal 1 at SFO International?
Review of Iberia Flight 6275 from Madrid to Chicago
Vegetarian food in Waikiki
Dish Network Scam
Fedex Stolen iPhone
Fee for ending eBay auction early
PayPal Email Scam Example
Send email address through eBay
How to connect Dish Network remote to a new TV?
Do Tennis Players Get Paid for Davis Cup?
What is a gazetted holiday?
American Vocabulary
Introduction
What is a pop quiz?
What does back burner mean?
What is a pissing contest?
What does lets play it by ear mean?
Earns The Big Bucks?
What does shady mean?
It all boils down to?
What is crunch time?
Game Time Decision?
Catch Off Guard?
What is an alpha male?
What is a hard stop?
Take Conversation Off Line?
What is hump day?
Putting Lipstick On a Pig?
Picking somebodys brain?
What is a pow wow?
Pushing the Envelope?
6 to one half dozen to the other
Reinvent the Wheel?
What does in a row mean?
What is a stones throw away?
What is a red flag?
What is a fire drill?
Meaning of where theres smoke theres fire
Meaning of et al
Meaning of out of commission?
Meaning of fly by night?
What does flight risk mean?
What does catch wind mean?
What is a brain fart?

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

What does make a killing mean?


In tennis whats a bagel?
What is a bounced check?
What does shortchange mean?
What does it mean to clock out?
What is shock value?
What does be the bigger man mean?
What does rube mean?
What is careerism?
What is a haunt?
Meaning of get feet wet?
Meaning of changing of the guard?
What is a hard copy?
What does brush with death mean?
In tennis, what is a pusher?
What does OTE mean in sales?
What does pay lip service mean?
What does tip of the iceberg mean?
What is an advert?
In the 11th hour meaning
Gentlemans C meaning
Meaning of teetotalar
Hala Madrid Meaning
Make your mark meaning
Shameless Plug Meaning
Low Hanging Fruit Meaning
Successism meaning
See eye to eye meaning
Rob Peter to Pay Paul meaning
Case in point meaning
Bait and Switch Meaning
Pardon My French Meaning
Throw him under the bus meaning
Wrong line of work meaning
My cue to leave meaning
What is a buzzkill?
Coined the Term Meaning
Elephant in the room meaning
Winging it meaning
Touch and go meaning
Hold my own meaning
Throw a line meaning
Skin in the game meaning
Brain dump meaning
He had the last laugh meaning
Call it a night Meaning
Speak off the cuff meaning
He has a chip on his shoulder meaning
Touch base meaning
On the house meaning
What are meeting minutes?
What is a low life?
What are brownie points?
Show True Colors Meaning
What does legit mean?
Just a heads up meaning
On the line meaning
Cream of the Crop meaning

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Right as Rain Meaning


Hat in hand meaning
What is a cake eater?
What is a second wind?
Bush league move meaning
Skating on thin ice meaning
Last straw meaning
At my wits end meaning
At the end of my rope meaning
At Large Meaning
What is tunnel vision in slang?
Do me a solid meaning
In a pigs eye meaning
Wear emotions on sleeve meaning
Keep plugging away definition
He is toast meaning
What is smart money?
On the lam meaning
Living large meaning
Hold the fort down meaning
Lay low meaning
Over the hill meaning
Out of the question meaning
Runs a tight ship meaning
Around the corner meaning
Technical Vocabulary
Introduction
What is a soft launch in software?
What is a software generalist?
What is a staging environment?
What is deprecated code?
What is syntactic sugar?
What is a turnkey solution?
What is a White hat hacker?
What is web root?
What is the LAMP stack?
What is GoF in design patterns?
What is a hack in software?
What is hard coding in Java?
Science Questions
Science Questions Introduction
What is the longest earthquake ever?
Are all volcanoes made of lava?
Why do rivers wind?
What makes rivers run?
Does the Mississippi River form a delta?
Do glaciers ever melt?
What is an ephemeral river?
What is the snout of a glacier?
Are there any rivers in the desert?
How much of the worlds land is covered by desert?
Do Caves Last Forever?
What are gallery caves?
What is the worlds longest cave?
What is the name for an expert on caves?
Who first realized earth circles the sun?
Why does the Moon look the same size as the Sun?
How do rockets work in space?

How many satellites are launched each year?


Does Pentagon know where every satellite is?
What planets have been visited by spacecrafts?
What tree is the symbol of Canada?
Why dont all trees lose their leaves?
Do all plants grow from seeds?
Are fruits seeds?
Are any vegetables also fruits?
Why do flowers have pretty colors?
Problems with the green revolution?
What are the largest seeds?
Do any flowers bloom for just a day?
How many plants are edible?
Has any woman ever run a 4 minute mile?
Did women ever put deadly nightshade in their eyes?
How can a willow tree cure a headache?
Does Coca Cola come from same plant as cocaine?
What plant has two different flowers?
What trees make wood?
What trees are used to make cricket bats?
What is the worlds worst smelling flower?
Is there a plant that eats frogs?
What plant did the Egyptians use for writing?
How do plants find water in the desert?
How often does it rain in Chiles Atacama desert?
Is the snow pink in Antarctica?
What frog makes arrows poisonous?
Do reindeers really pull sleighs?
Whats the difference between a moose and an elk?
Whats the difference between a reindeer and a caribou?
Why is a grizzly bear grizzly?
Do wolves really howl at the moon?
Do all penguins live in the Antarctic?
What bird never sees the sunset?
Do zebras neigh like horses?
Whats the difference between a male lion and a female?
Can crocodiles climb trees?
Does a mother crocodile carry babies between her teeth?
Are crocodiles like dinosaurs?
What animal can jump the highest?
Do vultures hunt?
Difference between a buffalo and a bison?
Who first wore trousers?
Which parts of the body are most sensitive to heat?
What country has the most arable land?
How long can a cheetah run?

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Find a Job

What:
title, keyw ords

Where:
city, state, or zip

Find Jobs

jobs by

Email
Country
Send

How do database indexes work? And, how do indexes help? Provide a


tutorial on database indexes.
Lets start out our tutorial and explanation of why you would need a database index by going through
a very simple example. Suppose that we have a database table called Employee with three columns
Employee_Name, Employee_Age, and Employee_Address. Assume that the Employee table has
thousands of rows.
Now, lets say that we want to run a query to find all the details of any employees who are named
Jesus? So, we decide to run a simple query like this:

SELECT * FROM Employee


WHERE Employee_Name = 'Jesus'

What would happen without an index on the table?

Once we run that query, what exactly goes on behind the scenes to find employees who are named
Jesus? Well, the database software would literally have to look at every single row in the Employee
table to see if the Employee_Name for that row is Jesus. And, because we want every row with the
name Jesus inside it, we can not just stop looking once we find just one row with the name Jesus,
because there could be other rows with the name Jesus. So, every row up until the last row must be
searched which means thousands of rows in this scenario will have to be examined by the database
to find the rows with the name Jesus. This is what is called a full table scan.

How a database index can help performance


You might be thinking that doing a full table scan sounds inefficient for something so simple
shouldnt software be smarter? Its almost like looking through the entire table with the human eye
very slow and not at all sleek. But, as you probably guessed by the title of this article, this is where
indexes can help a great deal. The whole point of having an index is to speed up search queries
by essentially cutting down the number of records/rows in a table that need to be
examined.

What is an index?
So, what is an index? Well, an index is a data structure (most commonly a B- tree) that stores the
values for a specific column in a table. An index is created on a column of a table. So, the key points
to remember are that an index consists of column values from one table, and that those values are
stored in a data structure. The index is a data structure remember that.
Subscribe to our newsletter for more free interview questions.

What kind of data structure is an index?


B- trees are the most commonly used data structures for indexes. The reason B- trees are the most
popular data structure for indexes is due to the fact that they are time efficient because look-ups,
deletions, and insertions can all be done in logarithmic time. And, another major reason B- trees are
more commonly used is because the data that is stored inside the B- tree can be sorted. The RDBMS
typically determines which data structure is actually used for an index. But, in some scenarios with
certain RDBMSs, you can actually specify which data structure you want your database to use when
you create the index itself.

How does a hash table index work?

Hash tables are another data structure that you may see being used as indexes these indexes are
commonly referred to as hash indexes. The reason hash indexes are used is because hash tables are
extremely efficient when it comes to just looking up values. So, queries that compare for equality to a
string can retrieve values very fast if they use a hash index. For instance, the query we discussed
earlier (SELECT * FROM Employee WHERE Employee_Name = Jesus) could benefit from a hash index
created on the Employee_Name column. The way a hash index would work is that the column value
will be the key into the hash table and the actual value mapped to that key would just be a pointer to
the row data in the table. Since a hash table is basically an associative array, a typical entry would
look something like Jesus => 0x28939, where 0x28939 is a reference to the table row where Jesus
is stored in memory. Looking up a value like Jesus in a hash table index and getting back a reference
to the row in memory is obviously a lot faster than scanning the table to find all the rows with a value
of Jesus in the Employee_Name column.

The disadvantages of a hash index


Hash tables are not sorted data structures, and there are many types of queries which hash indexes
can not even help with. For instance, suppose you want to find out all of the employees who are less
than 40 years old. How could you do that with a hash table index? Well, its not possible because a
hash table is only good for looking up key value pairs which means queries that check for equality
(like WHERE name = Jesus'). What is implied in the key value mapping in a hash table is the
concept that the keys of a hash table are not sorted or stored in any particular order. This is why
hash indexes are usually not the default type of data structure used by database indexes because
they arent as flexible as B- trees when used as the index data structure. Also see: Binary trees versus
Hash Tables.

What are some other types of indexes?


Indexes that use a R- tree data structure are commonly used to help with spatial problems. For
instance, a query like Find all of the Starbucks within 2 kilometers of me would be the type of query
that could show enhanced performance if the database table uses a R- tree index.
Another type of index is a bitmap index, which work well on columns that contain Boolean values (like
true and false), but many instances of those values basically columns with low selectivity.

How does an index improve performance?

Because an index is basically a data structure that is used to store column values, looking up those
values becomes much faster. And, if an index is using the most commonly used data structure type

a B- tree then the data structure is also sorted. Having the column values be sorted can be a major
performance enhancement read on to find out why.
Lets say that we create a B- tree index on the Employee_Name column This means that when we
search for employees named Jesus using the SQL we showed earlier, then the entire Employee table
does not have to be searched to find employees named Jesus. Instead, the database will use the
index to find employees named Jesus, because the index will presumably be sorted alphabetically by
the Employees name. And, because it is sorted, it means searching for a name is a lot faster because
all names starting with a J will be right next to each other in the index! Its also important to note
that the index also stores pointers to the table row so that other column values can be retrieved
read on for more details on that.

What exactly is inside a database index?


So, now you know that a database index is created on a column in a table, and that the index stores
the values in that specific column. But, it is important to understand that a database index does not
store the values in the other columns of the same table. For example, if we create an index on the
Employee_Name column, this means that the Employee_Age and Employee_Address column values
are not also stored in the index. If we did just store all the other columns in the index, then it would
be just like creating another copy of the entire table which would take up way too much space and
would be very inefficient.

An index also stores a pointer to the table row


So, the question is if the value that we are looking for is found in an index (like Jesus) , how does it
find the other values that are in the same row (like the address of Jesus and his age)? Well, its quite
simple database indexes also store pointers to the corresponding rows in the table. A pointer is just
a reference to a place in memory where the row data is stored on disk. So, in addition to the column
value that is stored in the index, a pointer to the row in the table where that value lives is also stored
in the index. This means that one of the values (or nodes) in the index for an Employee_Name could
be something like (Jesus, 0x82829), where 0x82829 is the address on disk (the pointer) where the
row data for Jesus is stored. Without that pointer all you would have is a single value, which would
be meaningless because you would not be able to retrieve the other values in the same row like the
address and the age of an employee.

How does a database know when to use an index?


When a query like SELECT * FROM Employee WHERE Employee_Name = Jesus is run, the
database will check to see if there is an index on the column(s) being queried. Assuming the
Employee_Name column does have an index created on it, the database will have to decide whether it
actually makes sense to use the index to find the values being searched because there are some
scenarios where it is actually less efficient to use the database index, and more efficient just to scan
the entire table. Read this article to understand more about those scenarios: Selectivity in SQL.

Can you force the database to use an index on a query?

Generally, you will not tell the database when to actually use an index that decision will be made by
the database itself. Although it is worth noting that in most databases (like Oracle and MySQL), you
can actually specify that you want the index to be used.

How to create an index in SQL:


Heres what the actual SQL would look like to create an index on the Employee_Name column from
our example earlier:

CREATE INDEX name_index


ON Employee (Employee_Name)

How to create a multi-column index in SQL:


We could also create an index on two of the columns in the Employee table , as shown in this SQL:

CREATE INDEX name_index


ON Employee (Employee_Name, Employee_Age)

What is a good analogy for a database index?


A very good analogy is to think of a database index as an index in a book. If you have a book about
dogs and you are looking for the section on Golden Retrievers, then why would you flip through the
entire book which is the equivalent of a full table scan in database terminology when you can just
go to the index at the back of the book, which will tell you the exact pages where you can find
information on Golden Retrievers. Similarly, as a book index contains a page number, a database index
contains a pointer to the row containing the value that you are searching for in your SQL.

What is the cost of having a database index?


So, what are some of the disadvantages of having a database index? Well, for one thing it takes up
space and the larger your table, the larger your index. Another performance hit with indexes is the
fact that whenever you add, delete, or update rows in the corresponding table, the same operations
will have to be done to your index. Remember that an index needs to contain the same up to the
minute data as whatever is in the table column(s) that the index covers.
As a general rule, an index should only be created on a table if the data in the indexed column will be
queried frequently.
You should also read more about normalization, and also check out the example of first normal form.

Hiring? Job Hunting? Post a JOB or your RESUME on our JOB BOARD >>
Subscribe to our newsletter for more free interview questions.

Previous...
Next...

shriyansh dhariwal
Hi,
Indeed a very clear and to the point explanation.
I have a question in the section How does a database know when to use an index?.
Suppose I am using a query like
Select * from Employee where employee_age >30 and employee_name = Jesus
Will it still use the index made for employee_name as it having employee_age>30 condition in
the where clause or the index will only be used when there is only employee_name condition
in the where clause?
Thanks & regards,
Shriyansh Dhariwal

.
Man, that was really good explanation. Thank you very much!

Md Farooq
I love the way concepts are explained here:-)

gyana nayak
Thanks a lot.. Please explain about non-clustered index as well .
thanks again.

AB_kyusak
sexy explaination

Steve
If the index is HashTable and there are many employees with name Jesus then how can
Hashtable keep multiple row addresses for a single key Jesus.

Amade Omar Ismael


I want to know if
I would have a key Jesus
and have a pointer to table where the two other Jesus will be.
Like:
Employee_Name
Jesus Anthony
Jesus Pert
Jesus Louis
B tree:
Jesus
>Pointer to a table that I will find all Jesus:
Jesus ROWID
JESUS ROWID
JESUS -ROW ID

Amade Omar Ismael


Hi.
If you create an Index with Employee_Name with the values: Jesus, Jesus, Jesus, Chris, Chris.
How many keys it would have?
2 keys? if its 2 keys where is the 2 Jesus and 1 Chris would be?

surbhi sharma
very very nice post.quite simple,easy and understanding ..thanks

Shanthi Erukulla
Till now I could not understand use of indexes Now I got it very clearly Thanks

Mrityunjaykumar Gupta
good explanation

Seun
Wow, best explanation!!!

TR

I was reading and reading looking for an explanation of how the index points to more than one
instance Jesus in the Savior column.

Gaurav k
i think this you have to decide and not the database as index is created by the user and not
automatically by database

Sid
I just couldnt resist myself admiring this article. Excellent job! (Y)

greg
Great job. help me a lotThank you

wolex
This is a beautiful piece.

Nikhil Ponnuru
veryy nice and intuitive!!

John Leonard Javiniar


What is the advantage of creating a multi-column index over a single column index? Is it just
the same with creating multiple single column indexes?

crazy
I am a bit confused between Index and non clustered Index.What is the difference between
Index and non clustered Index.They boths seem to be same thing?

Shail
Actually, I was not going to read the article seeing the size of page. But Once I read initial few
lines, I couldnt stop before reading complete article. Nice one.
Thanks

Anonymous
it is very clear thank you

Srinivas
Excellent Explanation Thank You.

Mai
excellent explanation!

John
great explanation !!!

Adam Zerner
I think these explanations could really benefit from some accompanying diagrams.

Zeetac
Awesome tutorial on Index. Can crack any developer interview at any level with this
knowledge. Must read for interview aspiring candidates. Great Job. The best Article on index
read so far. Simple and easy to grassp.

Vikram Maduri
nice article, found what i was looking for. thank you

m6106918
Thank you! much better than I learned in school

sqlgeek
indexing on age will sort the data based on the age. so it will only look into the partition where
the age is < 50 and won't look into other partition

Marsi
thank you:) good explanation

bala
Really great explanation. Try to provide all other concepts in sql

aditi bhavsar

Very good article. clearly and well explained.!

BSR
Good one. Thank you.

Cool
Please provide SAS ineterview questions as well

ananth
Clean explanation, you didnt provide the references for this article.

qiao
best explanation, I wish i have found this site sooner

Raul RS
Very nice explaination

Askar Khan
Good Job thanks

JG
..

vishnu
nice explanation on indexingthanks

Alton Douglas
it depends on how the index was created
if (CREATE INDEX ) it will return all/duplicate records
if (CREATE UNIQUE INDEX ) it will return unique records

Shikar
Nice clear explanation. Better if syntax for B+ index & Hash index given separately.

Suraj ambulkar
Excellent explanation

Anurag
very acute explanation.Love it !!!!!

Kriti
Feels like I am receiving a classroom training from a expert tutor. Each word is so explanatory.
Thank you very much for writing these articles. Best explanation so far. Great Job !!!

prakash
if the search on indexed column Employee_name=jesus found that there are more than one
persons name is jesus, then how it will work

deepti
very good explanation. thank you

Sourabh
Its totally Amazing! Thanks a lot!

Akki
Explained very well in simple and easy understandable language. Thanks a lot for this.

rodrigopiovezan
No. See this: http://use-the-index-luke.com/sql/myth-directory/indexes-can-degenerate

Henry Le
its great, helped me a lot. Thanks!

sumanth
How to see that index

Mahesh
Good explanation, but my doubt is if we created index on some columns which having 1000
rows in it and then we added more 100 rows in it means now we have 1100 rows.then index
need to create again ?

Stephen S
Really nice explanation.

N
So much theory, many things are missing specially efficiency of indexes bases of their types
like int, string, date etc

Suba
Good One

I have learnt the basics of Indexing and Glad to see Jesus in this

article God Bless You

Suba
kvsuba@gam

chetan
very nice tutorial thanks much

Mansoor
Very well explanation. In few minutes it helped me revise all my concepts with extreme good
explanation. Successful effort

Amit Agrawal
well explain, thanks

Hemny Singh
does index automatically created for primary key ?

Emre
Jesus Christ! Very good explanation

Shekhar Bhabad
amazing explanation..

Peter

Jesus saves in a db?

Naveen Kocherla
Excellent explanation.Keep it up

Ryan
Very good article.
So, is an index already created on a Primary Key automatically?

rinx
very simplified explanationthanks

Damian
Something to add, have in mind if you use wildcard % in front of the string that you will look
for (example LIKE %Jesus) index will not help you at all (due to there are not way to predict
what can be appear at front, i.e.: Jhon Jesus, Mike Jesus, etc.)

Dima V
Yeah you will have to create an index on age.

Sudha Kumari
thanks!

tabide
More specifically, the most common used data structure for indexing database like mysql is B+
tree. B tree is quite different from B+ tree.

ff@gmail.com
kjkg

Kumar
This article is very good and thanks for provieding this info, also can you please give some
details on Cluster and Non-Cluster index like how the non-cluster stores the data with cluster
and without cluster index?

Guest

How the database system would come to know that there are only two values in "SEX"
column?
Will it not have to scan at least once to come to know that there are only two possible values
in this column?

smassey3
This was the most helpful discussion on index that I have found. Thanks so much.

navi kaish
its too much good discription..it clears my all ambiguaties.thanks a lot and plz carry
on.the plus point is you use very simple english.its gud work

GT
damn good article!

prabha
very clear explanation

varoon10
Thanks Fariha!

varoon10
THanks Ayush!

varoon10
Thanks Sam!

varoon10
Thanks Vuyani!

varoon10
Thanks Gaurav!

varoon10
Thanks Sajith!

varoon10

Thanks Sajeesh!

varoon10
Thanks Pankaj!

Bharath K H
Simply superb. Never expected it is this much easy to understand concepts. I clearly got it
what I wanted . and further looking for PL/SQL interview questions in this knowledge pool.

pankaj
great tute ever seen

Sajeesh
Wow.. simple and very clean explanation. Was very useful. Thanks a lot.

Sajith
Interesting writing stylecongrats!!

gaurav9936
beautiful explaination

Vuyani Billy Nyathikazi


wowclear and easy to understand..thanks

apurva
very nice explanationi appreciate you to create such a helpful site

Vijay Kumar Rajput


wow !!! that is what I was looking.awesome..tutorial. I was searching.some pointers on
index.. and could not stop my self to read all page Language of text is so easy and
explanatory
Thanks for posting it.. I m gonna following it..

JO GI
Good job sir..explanation view is best..

Vimal
Really it clears all my doubts.

Jyoti Gupta
Really very good explanation.. It helped me a lot.. thank you..

CM
Clear and Simple! Thanks

Manoj
Very Cool. One of the best explanation when i compared to other forums

Sam
Really it is simple to the core and yet gives in detail understanding of the start up required for
even a newbie to SQL/ Indexes. Awesome!

jimbob
Thanks that's a great introductory explanation!

abc
Hey great explaination.could you please upload an explaination for Normalization

N
Nice article. Thanks a lot.

Kumar Ankit
Nice explanation !

babu
Very good Explanation.

A
Good explanation but i am confused a bit. please explain me.
if my query is like this. select * from table where age<50. then how indexing is going to help
in this case. do i have to create index on age. or same index Employee_Name (for reference :Employee_Name="jesus") as explained above can help me.

fariha
great effort. fantastic explanation

AJ
Too good, everything in detail but not boring at all.

Hiral
Very nice explanation.

Ayush
Thanks for your wonderful explanation !!!! The book example said it all

Rajneesh Kaundal
good explanation of index.. Thanks

Deepak
excellent explanation, very impressivegood work, keep it up.

Dev
Good One

varoon10
THanks Raghav! Maybe I will write an e-book or something haha!

varoon10
Thanks Vimal!

varoon10
THanks Stefan!

varoon10
THanks Pritam!

varoon10
Thanks Kevin!

varoon10
THanks Vinoth!

varoon10
THanks Shafeeq!

varoon10
Thanks Azra!

varoon10
Thanks Amit!

varoon10
Thanks Prageeth!

varoon10
Thanks Alex!

varoon10
Thanks Harsh!

kevin
great work

Pritam
fantastic

Stefan
Great work

Vimal
Awesome. Clearly explained article..

raghav
awsome explanation ,you should write ur own bookthe way u explain is just amazing!!!

Alex
Excellent job explaining this concept so clearly. Thank-you!

Prageeth Jayasinghe
Really appreciate your great effort.

SirAmit Nathani
very good explanation:)

azra
good work

shafeeq
Great work .It helped me lot..thanks ..

Harsh Dev
Awesome explanation..great job

Vinoth
Superb Explanation.. thanks so much keep up the gud work

Would you like to thank ProgrammerInterview.com for being a helpful free


resource? Then why not tell a friend about us, or simply add a link to this page from
your webpage using the HTML below.
Link to this
page:
<a href=

Please bookmark with social media, your votes are noticed and appreciated:

Go to main content

Sign In

Home / Database / Oracle Database Online Documentation 11g Release 1 (11.1) / Data
Warehousing and Business Intelligence

Database VLDB and Partitioning


Guide

Page 5 of 13
Search
Search

This Book

This Release

FeedbackDownload
Share to:
Sha re to Facebook

Share to TwitterShare to EmailSha re to PrintShare to GmailSha re to Mo re

30

Categories

Home
Master Index
Master Glossary
Data Dictionary
SQL Keywords
Acronyms
Initialization Parameters
Error Messages

2 Partitioning Concepts
Partitioning enhances the performance, manageability, and availability of a wide variety
of applications and helps reduce the total cost of ownership for storing large amounts of

data. Partitioning allows tables, indexes, and index-organized tables to be subdivided


into smaller pieces, enabling these database objects to be managed and accessed at a
finer level of granularity. Oracle provides a rich variety of partitioning strategies and
extensions to address every business requirement. Moreover, since it is entirely
transparent, partitioning can be applied to almost any application without the need for
potentially expensive and time consuming application changes.
This chapter contains the following topics:

Basics of Partitioning

Benefits of Partitioning

Partitioning Strategies

Overview of Partitioned Indexes

Basics of Partitioning
Partitioning allows a table, index, or index-organized table to be subdivided into smaller
pieces, where each piece of such a database object is called a partition. Each partition
has its own name, and may optionally have its own storage characteristics.
From the perspective of a database administrator, a partitioned object has multiple
pieces that can be managed either collectively or individually. This gives the
administrator considerable flexibility in managing partitioned objects. However, from
the perspective of the application, a partitioned table is identical to a non-partitioned
table; no modifications are necessary when accessing a partitioned table using SQL
queries and DML statements.
Figure 2-1 offers a graphical view of how partitioned tables differ from non-partitioned
tables.
Figure 2-1 A View of Partitioned Tables

Description of "Figure 2-1 A View of Partitioned Tables"

Note:
All partitions of a partitioned object must reside in tablespaces of a single block size.

See Also:
Oracle Database Concepts for more information about multiple block sizes

Partitioning Key
Each row in a partitioned table is unambiguously assigned to a single partition. The
partitioning key is comprised of one or more columns that determine the partition where
each row will be stored. Oracle automatically directs insert, update, and delete
operations to the appropriate partition through the use of the partitioning key.

Partitioned Tables
Any table can be partitioned into a million separate partitions except those tables
containing columns with LONG or LONG RAW datatypes. You can, however, use tables
containing columns with CLOB or BLOB datatypes.

Note:

To reduce disk usage and memory usage (specifically, the buffer cache), you can store tables and
partitions of a partitioned table in a compressed format inside the database. This often leads to a
better scaleup for read-only operations. Table compression can also speed up query execution.
There is, however, a slight cost in CPU overhead.

See Also:
Oracle Database Concepts for more information about table compression

When to Partition a Table


Here are some suggestions for when to partition a table:

Tables greater than 2 GB should always be considered as candidates for


partitioning.

Tables containing historical data, in which new data is added into the newest
partition. A typical example is a historical table where only the current month's
data is updatable and the other 11 months are read only.

When the contents of a table need to be distributed across different types of


storage devices.

When to Partition an Index


Here are some suggestions for when to consider partitioning an index:

Avoid rebuilding the entire index when data is removed.

Perform maintenance on parts of the data without invalidating the entire index.

Reduce the impact of index skew caused by an index on a column with a


monotonically increasing value.

Partitioned Index-Organized Tables


Partitioned index-organized tables are very useful for providing improved performance,
manageability, and availability for index-organized tables.
For partitioning an index-organized table:

Partition columns must be a subset of the primary key columns

Secondary indexes can be partitioned (both locally and globally)

OVERFLOW data segments are always equi-partitioned with the table partitions

See Also:
Oracle Database Concepts for more information about index-organized tables

System Partitioning
System partitioning enables application-controlled partitioning without having the
database controlling the data placement. The database simply provides the ability to
break down a table into partitions without knowing what the individual partitions are
going to be used for. All aspects of partitioning have to be controlled by the application.
For example, an insertion into a system partitioned table without the explicit
specification of a partition will fail.
System partitioning provides the well-known benefits of partitioning (scalability,
availability, and manageability), but the partitioning and actual data placement are
controlled by the application.

See Also:
Oracle Database Data Cartridge Developer's Guide for more information about system partitioning

Partitioning for Information Lifecycle Management


Information Lifecycle Management (ILM) is concerned with managing data during its
lifetime. Partitioning plays a key role in ILM because it enables groups of data (that is,
partitions) to be distributed across different types of storage devices and managed
individually.

See Also:
Chapter 5, "Using Partitioning for Information Lifecycle Management" for more information about
Information Lifecycle Management

Partitioning and LOB Data


Unstructured data (such as images and documents) which is stored in a LOB column in
the database can also be partitioned. When a table is partitioned, all the columns will
reside in the tablespace for that partition, with the exception of LOB columns, which can
be stored in their own tablespace.
This technique is very useful when a table is comprised of large LOBs because they can
be stored separately from the main data. This can be beneficial if the main data is being
frequently updated but the LOB data isn't. For example, an employee record may

contain a photo which is unlikely to change frequently. However, the employee


personnel details (such as address, department, manager, and so on) could change.
This approach also means that cheaper storage can be used for storing the LOB data
and more expensive, faster storage used for the employee record.

Benefits of Partitioning
Partitioning can provide tremendous benefit to a wide variety of applications by
improving performance, manageability, and availability. It is not unusual for partitioning
to improve the performance of certain queries or maintenance operations by an order of
magnitude. Moreover, partitioning can greatly simplify common administration tasks.
Partitioning also enables database designers and administrators to tackle some of the
toughest problems posed by cutting-edge applications. Partitioning is a key tool for
building multi-terabyte systems or systems with extremely high availability
requirements.

Partitioning for Performance


By limiting the amount of data to be examined or operated on, and by providing data
distribution for parallel execution, partitioning provides a number of performance
benefits. These features include:

Partition Pruning

Partition-Wise Joins

Partition Pruning
Partition pruning is the simplest and also the most substantial means to improve
performance using partitioning. Partition pruning can often improve query performance
by several orders of magnitude. For example, suppose an application contains
an Orders table containing a historical record of orders, and that this table has been
partitioned by week. A query requesting orders for a single week would only access a
single partition of the Orders table. If the Orders table had 2 years of historical data,
then this query would access one partition instead of 104 partitions. This query could
potentially execute 100 times faster simply because of partition pruning.
Partition pruning works with all of Oracle's other performance features. Oracle will utilize
partition pruning in conjunction with any indexing technique, join technique, or parallel
access method.

Partition-Wise Joins

Partitioning can also improve the performance of multi-table joins by using a technique
known as partition-wise joins. Partition-wise joins can be applied when two tables are
being joined together and both tables are partitioned on the join key, or when a
reference partitioned table is joined with its parent table. Partition-wise joins break a
large join into smaller joins that occur between each of the partitions, completing the
overall join in less time. This offers significant performance benefits both for serial and
parallel execution.

Partitioning for Manageability


Partitioning allows tables and indexes to be partitioned into smaller, more manageable
units, providing database administrators with the ability to pursue a "divide and
conquer" approach to data management. With partitioning, maintenance operations can
be focused on particular portions of tables. For example, a database administrator could
back up a single partition of a table, rather than backing up the entire table. For
maintenance operations across an entire database object, it is possible to perform these
operations on a per-partition basis, thus dividing the maintenance process into more
manageable chunks.
A typical usage of partitioning for manageability is to support a "rolling window" load
process in a data warehouse. Suppose that a DBA loads new data into a table on a
weekly basis. That table could be partitioned so that each partition contains one week
of data. The load process is simply the addition of a new partition using a partition
exchange load. Adding a single partition is much more efficient than modifying the
entire table, since the DBA does not need to modify any other partitions.

Partitioning for Availability


Partitioned database objects provide partition independence. This characteristic of
partition independence can be an important part of a high-availability strategy. For
example, if one partition of a partitioned table is unavailable, then all of the other
partitions of the table remain online and available. The application can continue to
execute queries and transactions against the available partitions for the table, and
these database operations will run successfully, provided they do not need to access
the unavailable partition.
The database administrator can specify that each partition be stored in a separate
tablespace; the most common scenario is having these tablespaces stored on different
storage tiers. Storing different partitions in different tablespaces allows the database
administrator to do backup and recovery operations on each individual partition,
independent of the other partitions in the table. Thus allowing the active parts of the
database to be made available sooner so access to the system can continue, while the
inactive data is still being restored. Moreover, partitioning can reduce scheduled
downtime. The performance gains provided by partitioning may enable database
administrators to complete maintenance operations on large database objects in
relatively small batch windows.

Partitioning Strategies
Oracle Partitioning offers three fundamental data distribution methods as basic
partitioning strategies that control how data is placed into individual partitions:

Range

Hash

List

Using these data distribution methods, a table can either be partitioned as a single list
or as a composite partitioned table:

Single-Level Partitioning

Composite Partitioning

Each partitioning strategy has different advantages and design considerations. Thus,
each strategy is more appropriate for a particular situation.

Single-Level Partitioning
A table is defined by specifying one of the following data distribution methodologies,
using one or more columns as the partitioning key:

Range Partitioning

Hash Partitioning

List Partitioning

For example, consider a table with a column of type NUMBER as the partitioning key and
two partitions less_than_five_hundred and less_than_one_thousand.
The less_than_one_thousand partition contains rows where the following condition is
true:
500 <= partitioning key < 1000

Figure 2-2 offers a graphical view of the basic partitioning strategies for a single-level
partitioned table.
Figure 2-2 List, Range, and Hash Partitioning

Description of "Figure 2-2 List, Range, and Hash Partitioning"

Range Partitioning
Range partitioning maps data to partitions based on ranges of values of the partitioning
key that you establish for each partition. It is the most common type of partitioning and
is often used with dates. For a table with a date column as the partitioning key,
the January-2005 partition would contain rows with partitioning key values from 01-Jan2005 to 31-Jan-2005.
Each partition has a VALUES LESS THAN clause, which specifies a non-inclusive upper
bound for the partitions. Any values of the partitioning key equal to or higher than this
literal are added to the next higher partition. All partitions, except the first, have an
implicit lower bound specified by the VALUESLESS THAN clause of the previous partition.
A MAXVALUE literal can be defined for the highest partition. MAXVALUE represents a virtual
infinite value that sorts higher than any other possible value for the partitioning key,
including the NULL value.

Hash Partitioning
Hash partitioning maps data to partitions based on a hashing algorithm that Oracle
applies to the partitioning key that you identify. The hashing algorithm evenly
distributes rows among partitions, giving partitions approximately the same size.
Hash partitioning is the ideal method for distributing data evenly across devices. Hash
partitioning is also an easy-to-use alternative to range partitioning, especially when the
data to be partitioned is not historical or has no obvious partitioning key.

Note:

You cannot change the hashing algorithms used by partitioning.

List Partitioning
List partitioning enables you to explicitly control how rows map to partitions by
specifying a list of discrete values for the partitioning key in the description for each
partition. The advantage of list partitioning is that you can group and organize
unordered and unrelated sets of data in a natural way. For a table with a region column
as the partitioning key, the North America partition might contain values Canada, USA,
and Mexico.
The DEFAULT partition enables you to avoid specifying all possible values for a listpartitioned table by using a default partition, so that all rows that do not map to any
other partition do not generate an error.

Composite Partitioning
Composite partitioning is a combination of the basic data distribution methods; a table
is partitioned by one data distribution method and then each partition is further
subdivided into subpartitions using a second data distribution method. All subpartitions
for a given partition together represent a logical subset of the data.
Composite partitioning supports historical operations, such as adding new range
partitions, but also provides higher degrees of potential partition pruning and finer
granularity of data placement through subpartitioning. Figure 2-3 offers a graphical view
of range-hash and range-list composite partitioning, as an example.
Figure 2-3 Composite Partitioning

Description of "Figure 2-3 Composite Partitioning"

Composite Range-Range Partitioning

Composite Range-Hash Partitioning

Composite Range-List Partitioning

Composite List-Range Partitioning

Composite List-Hash Partitioning

Composite List-List Partitioning

Composite Range-Range Partitioning


Composite range-range partitioning enables logical range partitioning along two
dimensions; for example, partition by order_date and range subpartition
by shipping_date.

Composite Range-Hash Partitioning


Composite range-hash partitioning partitions data using the range method, and within
each partition, subpartitions it using the hash method. Composite range-hash
partitioning provides the improved manageability of range partitioning and the data
placement, striping, and parallelism advantages of hash partitioning.

Composite Range-List Partitioning


Composite range-list partitioning partitions data using the range method, and within
each partition, subpartitions it using the list method. Composite range-list partitioning
provides the manageability of range partitioning and the explicit control of list
partitioning for the subpartitions.

Composite List-Range Partitioning


Composite list-range partitioning enables logical range subpartitioning within a given list
partitioning strategy; for example, list partition by country_idand range subpartition
by order_date.

Composite List-Hash Partitioning


Composite list-hash partitioning enables hash subpartitioning of a list-partitioned object;
for example, to enable partition-wise joins.

Composite List-List Partitioning

Composite list-list partitioning enables logical list partitioning along two dimensions; for
example, list partition by country_id and list subpartition by sales_channel.

Partitioning Extensions
In addition to the basic partitioning strategies, Oracle Database provides partitioning
extensions:

Manageability Extensions

Partitioning Key Extensions

Manageability Extensions
These extensions significantly enhance the manageability of partitioned tables:

Interval Partitioning

Partition Advisor

Interval Partitioning
Interval partitioning is an extension of range partitioning which instructs the database to
automatically create partitions of a specified interval when data inserted into the table
exceeds all of the existing range partitions. You must specify at least one range
partition. The range partitioning key value determines the high value of the range
partitions, which is called the transition point, and the database creates interval
partitions for data beyond that transition point. The lower boundary of every interval
partition is the non-inclusive upper boundary of the previous range or interval partition.
For example, if you create an interval partitioned table with monthly intervals and the
transition point at January 1, 2007, then the lower boundary for the January 2007
interval is January 1, 2007. The lower boundary for the July 2007 interval is July 1, 2007,
regardless of whether the June 2007 partition was already created.
When using interval partitioning, consider the following restrictions:

You can only specify one partitioning key column, and it must be
of NUMBER or DATE type.

Interval partitioning is not supported for index-organized tables.

You cannot create a domain index on an interval-partitioned table.

You can create single-level interval partitioned tables as well as the following composite
partitioned tables:

Interval-range

Interval-hash

Interval-list

Partition Advisor
The Partition Advisor is part of the SQL Access Advisor. The Partition Advisor can
recommend a partitioning strategy for a table based on a supplied workload of SQL
statements which can be supplied by the SQL Cache, a SQL Tuning set, or be defined by
the user.

Partitioning Key Extensions


These extensions extend the flexibility in defining partitioning keys:

Reference Partitioning

Virtual Column-Based Partitioning

Reference Partitioning
Reference partitioning allows the partitioning of two tables related to one another by
referential constraints. The partitioning key is resolved through an existing parent-child
relationship, enforced by enabled and active primary key and foreign key constraints.
The benefit of this extension is that tables with a parent-child relationship can be
logically equi-partitioned by inheriting the partitioning key from the parent table without
duplicating the key columns. The logical dependency will also automatically cascade
partition maintenance operations, thus making application development easier and less
error-prone.
An example of reference partitioning is the Orders and OrderItems tables related to
each other by a referential constraint orderid_refconstraint.
Namely, OrderItems.OrderID references Orders.OrderID. The Orders table is range
partitioned on OrderDate. Reference partitioning
on orderid_refconstraint for OrderItems leads to creation of the following partitioned
table, which is equi-partitioned with respect to the Orderstable, as shown in Figure 24 and Figure 2-5.
Figure 2-4 Before Reference Partitioning

Description of "Figure 2-4 Before Reference Partitioning"

Figure 2-5 With Reference Partitioning

Description of "Figure 2-5 With Reference Partitioning"

All basic partitioning strategies are available for reference Partitioning. Interval
partitioning cannot be used with reference partitioning.

Virtual Column-Based Partitioning


In previous releases of the Oracle Database, a table could only be partitioned if the
partitioning key physically existed in the table. In Oracle Database 11g, virtual columns
remove that restriction and allow the partitioning key to be defined by an expression,
using one or more existing columns of a table. The expression is stored as metadata
only.
Oracle Partitioning has been enhanced to allow a partitioning strategy to be defined on
virtual columns. For example, a 10 digit account ID can include account branch
information as the leading 3 digits. With the extension of virtual column based
Partitioning, an ACCOUNTS table containing an ACCOUNT_ID column can be extended with
a virtual (derived) column ACCOUNT_BRANCH that is derived from the first three digits of
the ACCOUNT_IDcolumn, which becomes the partitioning key for this table.
Virtual column-based Partitioning is supported with all basic partitioning strategies,
including interval and interval-* composite partitioning.

Overview of Partitioned Indexes


Just like partitioned tables, partitioned indexes improve manageability, availability,
performance, and scalability. They can either be partitioned independently (global
indexes) or automatically linked to a table's partitioning method (local indexes). In
general, you should use global indexes for OLTP applications and local indexes for data
warehousing or DSS applications. Also, whenever possible, you should try to use local
indexes because they are easier to manage. When deciding what kind of partitioned
index to use, you should consider the following guidelines in order:
1. If the table partitioning column is a subset of the index keys, use a local index. If
this is the case, you are finished. If this is not the case, continue to guideline 2.
2. If the index is unique and does not include the partitioning key columns, then use
a global index. If this is the case, then you are finished. Otherwise, continue to
guideline 3.
3. If your priority is manageability, use a local index. If this is the case, you are
finished. If this is not the case, continue to guideline 4.
4. If the application is an OLTP one and users need quick response times, use a
global index. If the application is a DSS one and users are more interested in
throughput, use a local index.

See Also:

Chapter 6, "Using Partitioning in a Data Warehouse Environment" and Chapter 7, "Using Partitioning
in an Online Transaction Processing Environment" for more information about partitioned indexes
and how to decide which type to use

Local Partitioned Indexes


Local partitioned indexes are easier to manage than other types of partitioned indexes.
They also offer greater availability and are common in DSS environments. The reason
for this is equipartitioning: each partition of a local index is associated with exactly one
partition of the table. This enables Oracle to automatically keep the index partitions in
sync with the table partitions, and makes each table-index pair independent. Any
actions that make one partition's data invalid or unavailable only affect a single
partition.
Local partitioned indexes support more availability when there are partition or
subpartition maintenance operations on the table. A type of index called a local
nonprefixed index is very useful for historical databases. In this type of index, the
partitioning is not on the left prefix of the index columns.

See Also:
Chapter 4 for more information about prefixed indexes
You cannot explicitly add a partition to a local index. Instead, new partitions are added
to local indexes only when you add a partition to the underlying table. Likewise, you
cannot explicitly drop a partition from a local index. Instead, local index partitions are
dropped only when you drop a partition from the underlying table.
A local index can be unique. However, in order for a local index to be unique, the
partitioning key of the table must be part of the index's key columns.
Figure 2-6 offers a graphical view of local partitioned indexes.
Figure 2-6 Local Partitioned Index

Description of "Figure 2-6 Local Partitioned Index"

Global Partitioned Indexes


Oracle offers two types of global partitioned indexes: range partitioned and hash
partitioned.

Global Range Partitioned Indexes


Global range partitioned indexes are flexible in that the degree of partitioning and the
partitioning key are independent from the table's partitioning method.
The highest partition of a global index must have a partition bound, all of whose values
are MAXVALUE. This ensures that all rows in the underlying table can be represented in
the index. Global prefixed indexes can be unique or nonunique.
You cannot add a partition to a global index because the highest partition always has a
partition bound of MAXVALUE. If you wish to add a new highest partition, use
the ALTER INDEX SPLIT PARTITION statement. If a global index partition is empty, you can
explicitly drop it by issuing the ALTER INDEXDROP PARTITION statement. If a global index
partition contains data, dropping the partition causes the next highest partition to be
marked unusable. You cannot drop the highest partition in a global index.

Global Hash Partitioned Indexes


Global hash partitioned indexes improve performance by spreading out contention when
the index is monotonically growing. In other words, most of the index insertions occur
only on the right edge of an index.

Maintenance of Global Partitioned Indexes


By default, the following operations on partitions on a heap-organized table mark all
global indexes as unusable:
ADD (HASH)

COALESCE (HASH)

DROP

EXCHANGE

MERGE

MOVE

SPLIT

TRUNCATE

These indexes can be maintained by appending the clause UPDATE INDEXES to the SQL
statements for the operation. The two advantages to maintaining global indexes:

The index remains available and online throughout the operation. Hence no other
applications are affected by this operation.

The index doesn't have to be rebuilt after the operation.

Note:
This feature is supported only for heap-organized tables.
Figure 2-7 offers a graphical view of global partitioned indexes.
Figure 2-7 Global Partitioned Index

Description of "Figure 2-7 Global Partitioned Index"

Global Non-Partitioned Indexes


Global non-partitioned indexes behave just like a non-partitioned index.
Figure 2-8 offers a graphical view of global non-partitioned indexes.
Figure 2-8 Global Non-Partitioned Index

Description of "Figure 2-8 Global Non-Partitioned Index"

Miscellaneous Information about Creating Indexes on


Partitioned Tables
You can create bitmap indexes on partitioned tables, with the restriction that the bitmap
indexes must be local to the partitioned table. They cannot be global indexes.
Global indexes can be unique. Local indexes can only be unique if the partitioning key is
a part of the index key.

Partitioned Indexes on Composite Partitions


Here are a few points to remember when using partitioned indexes on composite
partitions:

Subpartitioned indexes are always local and stored with the table subpartition by
default.

Tablespaces can be specified at either index or index subpartition levels.


Previous Page
Page 5 of 13
Next Page

About Oracle
Contact Us
Legal Notices
Terms of Use
Your Privacy Rights

Copyright 2016, Oracle and/or its affiliates. All rights reserved.

About
Experts
Red Gate Oracle Tools
Log in

All Things Oracle

Full Articles
Webinars
Experts
Database Dev
App Dev
DBA
PL/SQL
APEX
Puzzles

Introduction to Table Partitioning


Jan Leers on 07 March 2013 with 14 comments

Divide and conquer is what Oracle was thinking with this one. Table partitioning is about optimizing
medium selectivity queries. The Oracle database has optimization techniques for high selectivity
queries, with the use of indexes. If we need to process all data in a big table, we have to live with the fact
it will take a while, but the engine will process the data as fast as possible. However, a medium selectivity
query needs just a portion of the data, for instance a tenth. This is to much data for indexes, to little data
for full table scans so the processing time might become rather long regarding the outcome.
Let me give you a brief explanation of how Oracle collects its data, and how table partitioning can help for
these queries. Do note this is not for everyone; Oracle Partitioning is an extra cost option, for Enterprise
Edition only.

Access methods in a nutshell


Oracle has two commonly used table access methods, full table access and access by rowid. For the
first method, Oracle reads all the blocks in a table, and applies filters afterwards. This might look like a lot
of overhead, but multiblock reads are used for reading large amounts of data in bulk. The access by rowid
is mostly used in conjunction with indexes. The index scan returns a rowid, and a single block read is
used to get the block were interested in. This looks like an interesting method, because we read a lot less
data. But when we need a lot of records, this means a lot of small operations that need to be set up,
which brings a lot of overhead. Depending on your data, youre better off with multi block reads when
youre fetching more than 5% to 10% of the table.

Table partitioning to the rescue


When we store our data in a non-partitioned table, without indexes, we will always have a full table scan.
Consider following code:

CREATE TABLE big_t AS


SELECT ROWNUM AS n_uniq
, MOD(ROWNUM,10) AS n10

,
,
FROM
WHERE

MOD(ROWNUM,100000) AS n100k
RPAD(rownum,1000,'A') AS filler
all_source, all_source
rownum<= 100000;

SELECT COUNT(1) FROM big_t;


COUNT(1)
-------100000
Task completed in 2,249 seconds
SELECT COUNT(1)
FROM big_t
WHERE n10 = 1;
COUNT(1)
-------10000
Task completed in 2,328 seconds

With table partitioning, a table can be physically divided into multiple smaller tables, called partitions,
while logically it stays one table. This means your code stays the same, but full partition scans will be
executed instead of a full table scan.
These partitions are created based on a key. Depending on which value a certain column has, the record
will be stored in a certain partition. Its important to choose a column that is often used in queries as our
key.

CREATE TABLE big_t_list


PARTITION BY LIST(n10)
(partition part1 VALUES (1)
,partition part2 VALUES (2,3,4)
,partition part3 VALUES (DEFAULT))
AS SELECT *
FROM big_t;
SELECT table_name, tablespace_name, blocks, num_rows

FROM user_tables
WHERE table_name LIKE 'BIG_T%';
TABLE_NAME TABLESPACE_NAME BLOCKS NUM_ROWS
---------- --------------- ------ -------BIG_T
USERS
14449
100000
BIG_T_LIST
14536
100000
SELECT table_name, partition_name, high_value, tablespace_name, blocks,
num_rows
FROM user_tab_partitions
WHERE table_name LIKE 'BIG_T%';
TABLE_NAME
---------BIG_T_LIST
BIG_T_LIST
BIG_T_LIST

PARTITION_NAME
--------------PART1
PART2
PART3

HIGH_VALUE
---------1
2, 3, 4
DEFAULT

TABLESPACE_NAME BLOCKS NUM_ROWS


--------------- ------ -------USERS
1461
10000
USERS
4364
30000
USERS
8711
60000

The big advantage of partitioning is the possibility for partition pruning. When we look for a value of 1
in column N10, we know we will only find this in partition PART1, so we dont need to access the other
partitions, and our query will execute ten times as fast. When we need all values, it will scan all partition,
and there will only be a small overhead.

SELECT COUNT(1) FROM big_t_list;


COUNT(1)
-------100000
Task completed in 3,601 seconds
SELECT COUNT(1) FROM big_t_list WHERE n10 = 1;
COUNT(1)
-------10000
Task completed in 0,537 seconds

As you can see, the partition pruning makes an enormous difference, going from 2.3 seconds to 0.5
seconds.

Table partitioning methods


Table partitioning already exists since 8i, but a lot of new possibilities were added since 11g. The different
types of partitioning are:

Range partitioning
The table is divided in ranges, typically used for date ranges. This is beneficial when the filters using
inbetween, greater than or less than. It is able to skip all partitions not in the range.

CREATE TABLE orders_range(order_id NUMBER


,client_id NUMBER
,order_date DATE)
PARTITION BY RANGE(order_date)
(PARTITION orders2011 VALUES LESS THAN (to_date('1/1/2012','dd/mm/yyyy'))
,PARTITION orders2012 VALUES LESS THAN (to_date('1/1/2013','dd/mm/yyyy'))
,PARTITION orders2013 VALUES LESS THAN (MAXVALUE));

When inserting a record that does not belong to any of the partitions, an ORA-14400 error will be raised.
If you create a partition with MAXVALUE, it will be used as default partition. New partitions can be added
or dropped manually when needed, or they can be created automatically with interval partitioning.

CREATE TABLE orders_range(order_id NUMBER


,client_id NUMBER
,order_date DATE)
PARTITION BY RANGE(order_date)
INTERVAL (NUMTOYMINTERVAL(1,'year'))
(PARTITION orders2011 VALUES LESS THAN (to_date('1/1/2012','dd/mm/yyyy'))
,PARTITION orders2012 VALUES LESS THAN
(to_date('1/1/2013','dd/mm/yyyy')));

List partitioning
A limited set of possible values is given; rows containing the same value are grouped. This can be used
for columns with few distinct values, when all values are known, like department or country. It can be
beneficial to group values together that are combined in filters.
To avoid the ORA-14400 error, one can use the DEFAULT-keyword.

CREATE TABLE clients_list(client_id NUMBER


,name VARCHAR2(50)
,country VARCHAR2(2))
PARTITION BY LIST(country)
(PARTITION clients_benelux VALUES ('BE','NE','LU')
,PARTITION clients_uk
VALUES ('UK')
,PARTITION clients_other
VALUES (DEFAULT));

Hash partitioning
A value is hashed, and random distribution occurs. This is used with many distinct values, when there are
no searches on ranges. The advantages can be a more evenly distribution than with range partitioning.

CREATE TABLE clients_hash(client_id NUMBER


,name VARCHAR2(50)
,country VARCHAR2(2))
PARTITION BY HASH(name)
PARTITIONS 5;

Composite partitioning
A partition can be subpartitioned by any of the previous methods, in any combination since 11g. This will
allow more queries to benefit from table partitioning. Partition pruning will occur when filtering on both
keys or only one of the keys.

CREATE TABLE clients_hl(client_id NUMBER


,name
VARCHAR2(50)
,country
VARCHAR2(2))
PARTITION BY LIST(country)
SUBPARTITION BY HASH(name)
SUBPARTITIONS 5
(PARTITION clients_benelux VALUES ('BE','NE','LU')
,PARTITION clients_uk
VALUES ('UK')
,PARTITION clients_other
VALUES (DEFAULT));

Refpartitioning

Partitioning is also possible on parent and child relations. When the parent table is partitioned, the child
table can be partitioned based on the foreign key. For instance when the ORDERS table is partitioned
on ORDER_DATE, the ORDER_LINES table can be partitioned on the order date as well, without
storing the actual value in the ORDER_LINES table. This is very beneficial when joining the two tables
on the foreign key.

CREATE TABLE orders_range(order_id NUMBER PRIMARY KEY


,order_date DATE)
PARTITION BY RANGE(order_date)
(PARTITION orders2011 VALUES LESS THAN (to_date('1/1/2012','dd/mm/yyyy'))
,PARTITION orders2012 VALUES LESS THAN (to_date('1/1/2013','dd/mm/yyyy'))
,PARTITION orders2013 VALUES LESS THAN (MAXVALUE));
CREATE TABLE order_lines (order_line_id NUMBER PRIMARY KEY
,order_id NUMBER NOT NULL
,line VARCHAR2(50)
,CONSTRAINTo_ol_fk FOREIGN KEY (order_id) REFERENCES
orders_range(order_id))
PARTITION BY REFERENCE (o_ol_fk);

Partitioned indexes
Not only tables can be partitioned, but indexes can become very large objects as well. The indexes for
partitioned tables can be stored on three different ways:
o
o
o

Non partitioned: No partitioning applied


Globally partitioned: The index is not partitioned on the same key as the table
Locally partitioned: The index is partitioned on the same key as the partitioned table

Which type of index partitioning type you chose is depended on the query it needs to support. If the filter
always contains the key, local indexes can be used, which are easier to manage. Globally partitioned
indexes offer higher flexibility.

Now lets start partitioning!


If you can afford this option, it will speed up your queries dramatically, without changing anything to your
code. Since 11g partitions have been greatly enhanced, but they can be used as from Oracle 8i.
If you cannot use this option, the concept might still be a life saver, dividing your big tables into smaller
ones. This will be very handy for recent data and archived data, but your code will become very complex,
very quickly.
inShare

Jan Leers
Jan Leers is an Oracle Certified Professional/Expert, working as an Oracle Consultant for over 5 years.
By working at some of Belgiums largest companies during this period, Jan has gained a tremendous
insight in Oracle internals, making him an expert when it comes to performance tuning, data integration
and advanced SQL & PL/SQL.

Comments
Trackbacks

14 Comments

1.

Niket kumar
15/04/2013 Reply

Thanks for the article...

2.

yacho98
24/01/2014 Reply

Nice and easy to understand.


Thanks

3.

Kamal
27/03/2014 Reply

In a sales data table there is a column sales_date and this table is having data for the whole year for 2013
January to December. This table is range partitioned using sales_date by month. So, it will have 12
partitions. Is it possible to have 24 global partition indexes on this table ?

4.

Mike
30/05/2014 Reply

Really well written and explain - one of the best and clearly written articles I have seen on Oracle
Partitioning.

5.

Abhijit
24/12/2014 Reply

Is there any option to use concept like INTERVAL in 10g?

6.

Rachna
21/01/2015 Reply

Thanks for the explaination,it is very helpful. I have a query and one particular scenario, Will partition help
when i need to extract all records of the one big table based on some joins with other tables. Even If i
make partitions virtually oracle will have to search from all the partitions. for such cases how can i
improve the perofrmance .

Anshu
03/08/2016 Reply

If you need to perform joins & scan big tables, partitioning doesn't matter for most part, however you
should improve your join operation by converting most (or all) of it to subqueries.

7.

Gopikrishna Kota
29/04/2015 Reply

It is very good a explanation for learners

Anshu
03/08/2016 Reply

If you need to perform joins & scan big tables, partitioning doesn't matter for most part, however you
should improve your join operation by converting most (or all) of it to subqueries.

8.

pez

06/10/2015 Reply

how do i add a partition to an existing table

Anshu
03/08/2016 Reply

Existing tables can't be partitioned. You'll need to create a new one with partitioning clause, as a copy of
your existing table. Once ready, you may exchange the new one with your existing table using
DBMS_REDEFINITION .
Example to start you up :
CREATE TABLE new_table
PARTITION BY LIST(n10)
(partition part1 VALUES (1)
,partition part2 VALUES (2,3,4)
,partition part3 VALUES (DEFAULT))
AS SELECT *
FROM existing_table;

9.

Das
05/08/2016 Reply

Elegant !

10.

vijay kumar
06/09/2016 Reply

Hi
when i dont have any primary key and date column, instead of that i have composite key and date
column with number format so how can i do partition in that table

11.

subesh
18/11/2016 Reply

cqn you list partiotn existing table like


alter table table_name
add partiotn by list(column_name)
(PARTITION clients_benelux VALUES ('BE','NE','LU')
,PARTITION clients_uk
VALUES ('UK')
,PARTITION clients_other VALUES (DEFAULT));

Leave a response

* Required

* Required

Notify me of followup comments via e-mail. You can also subscribe without commenting.

Submit comment

How do you manage your database deployments?


DBMaestro

Flyway

Liquibase

Redgate Schema Compare for Oracle

Redgate Source

Control for OracleOther:

VoteView Results

Cary Millsaps latest book

The Method R Guide to Mastering Oracle Trace Data, Second Edition contains the richest description of
Oracle extended SQL trace data that youll ever find, and over 100 pages of worked examples, using the
software tools built by Carys Method R Corporation.
Buy now

RMOUG News

Please make an end-of-year tax-deductible donation to an RMOUG scholarship


Meetup with Monty Widenius (MySQL/MariaDB founder)
BYOC Bring Your Oracle Challenge
Summer 2016 Quarterly Educational Workshop
DBLabs meetup, Sat 09-July: APEX hands-on labs

ODTUG News

Tim and Cameron's Most Excellent Farewell!


Get a Taste of Kscope17 in San Antonio!
Andy Colvin: Putting 12.2 to the Test
Upcoming ODTUG Webinars

Categories

10g (12)
11g (48)
12c (57)
8i (3)
9i (3)
All Things Oracle Full Articles (209)
APEX (29)
Application Development (39)
Backup and Recovery (3)
Continuous Delivery (2)
Database Administration (141)
Database Development (190)
eBook (5)
EM12c (2)
Enterprise Manager (2)
Oracle Cloud (6)
Oracle Database (140)
Oracle Forms (1)
Performance Tuning (53)
PL/SQL (52)
Polls (2)
Puzzles (7)
RAC (4)
Troubleshooting (45)
Uncategorized (8)
Video (15)
Webinar (44)

Subscribe to All Things Oracle

Name:

Email:

Job Title:

Subscribe

2016 Redgate Software and associated content authors All Rights Reserved Privacy policy Terms and

Conditions

CONSULTING

TRAINING

BLOG

FREE STUFF

CONTACT US

How To Decide if You Should Use


Table Partitioning
March 6, 2012Kendra Little130 comments
Great volumes have been written about table partitioning. Its a complex feature and you can read
for days to just understand how you might apply it. But will it improve performance for you? Table
partitioning produces great benefits for some applications, but causes giant headaches for others.
How do you know if you should invest your time in table partitioning?
I can help.

SQL Server Table Partitioning: The Basics


Lets nerd out for a bit on what table partitioning does in SQL Server. First of all, this is an Enterprise
Edition feature. (Cha-ching! $$$.) You can test it in developer edition, but if you want to use it in
production, you gotta make sure its worth the licensing costs as well as your time.
Table partitioning allows tables or indexes to be stored in multiple physical sections a partitioned
index is like one large index made up of multiple little indexes. Each chunk, or partition, has the
same columns just a different range of rows. Table partitioning is transparent. This means a
partitioned heap, clustered index, or non-clustered index can be referenced as a single structure
although its stored in independent physical partitions. In other words, in theory you dont need to
change any code in the calling applications. (Is this true in reality? More on this later.)

An Textbook Example of Table Partitioning


Contoso Corporations Froyo Division has a 2TB database named FroyoReports. Each day, 10
million rows of sales data are loaded into a table named FroyoSales. Contoso Corp has employees
worldwide who query the data using SQL Server Reporting Services. Reports are run against
FroyoReports 24 x 7, although there is a two hour window each day where there is significantly
lighter load. 95% of reports run are against the most recent two months of data, and the DBA team
controls and can tune the queries run by each report. The Froyo DBA team needs to maintain only
13 months of data in the FroyoSales table. As a safety precaution, they prefer to keep three
additional months of data online, but do not want reports to access the older data.
Life used to be tough for the Froyo DBA team. Each night as data was loaded, reports repeatedly
blocked inserts. To help alleviate blocking, some reports were modified to have NOLOCK hints. This
meant that sometimes reports contained partial data for the most recent day, which caused
problems. Users were never really sure when data was finished loading and when it was safe to run
reports. The Froyo DBA team deleted old data on weekends, and that process also had problems.
There was additional blocking and deletes slowed performance significantly. To solve these
problems, the Froyo team implemented table partitioning. They partitioned the FroyoSales table by
date.
Each night, the Froyo team loads data with an automated process. First, it loads new fact data into a
fresh, empty table named FroyoSalesStaging.

A staging table loaded with data

Next, it adds indexes and constraints to FroyoSalesStaging so its structure matches Froyo sales.

Preparing a staging table to be switched in to a fact table

Then, they switch the single partition out of FroyoSalesStaging and into the partitioned table
FroyoSales. (This involves a few commands to prepare the metadata for the partitioned table prior to
the switch were going for an overview here.) This switch takes a brief moment, then all the new
data is visible to users.

Switching a partition from a staging table to a fact table

The Froyo team has also automated how they remove old data. Each night they switch the oldest
day which is now past their 13 month limit out from FroyoSales and into a table named
FroyoSalesArchive. (Similarly, theres a few commands to clean up metadata for FroyoSales after
the switch out.)

Switching a table partition to an archive table

Handy, isnt it?

The Main Features of Table Partitioning And the


Gotchas
Here are the big attractions for table partitioning, along with the fine print.

SWITCH That Partition


As you can see above, a whole partition can be switched into the table or switched out, allowing for
extremely fast loading and removal of large amounts of data. This is, in my opinion, the biggest
benefit of partitioning.
There are a couple of gotchas to be aware of. Switching in and switching out partitions can be very
fast, but an exclusive lock Called SCH-M, or Schema Modification lock is required. This means
you can get blocked from loading or removing data from your table potentially for a very long
time. Also, all of your enabled non-clustered indexes must be partition aligned to switch a partition
in. This means the partitioning key must be part of each of those indexes. If you need to maintain
uniqueness on a set of columns that doesnt include the partitioning key (which is often the case in
OLTP environments), this can pose a problem.

Query Performance on Partitioned Tables: Partition


Elimination and Beyond
SQL Server tries to identify when it can use limited parts of a partitioned table. The SQL Server
query optimizer may direct a query to only a single partition, multiple partitions, or the whole table.
Using fewer partitions than the entire table is called partition elimination.
Statistics are maintained for the entire partitioned table or index you dont get additional steps in
your histogram for each partition. This means that the SQL Server Query optimizer may still have a
very hard time knowing how much data is going to be returned by your query, and this difficulty will
increase as your table grows. The result may be slow queries.
Queries will perform better when you specify the partitioning key in the criteria (aka the where
clause). So, although partitioning is transparent, for existing applications, query tuning will almost
always be required.

Partition Management
Individual partitions may:

Be rebuilt individually, for clustered and nonclustered indexes alike.

Be set to read-only, via their filegroup gives you options to optimize backups

Live on different disk sub-systems less frequently accessed data can sit on slow disk.
Frequently accessed data can sit on faster disk. All this within the same table! You can move
a partition to faster or slower disk online with some virtualization and SAN solutions.

Theres a few things to be aware of:

You want to be careful about splitting partitions performance can be very slow.

In SQL Server 2005 and 2008, individual partitions may be rebuilt offline only. An entire
partitioned index may be rebuilt online but thats a bummer if your database is 247.

Setting a filegroup to read-only doesnt eliminate lock management overhead thats only
true for a read-only database.

Columnstore Indexes and Table Partitioning


Columnstore indexes are a really hot feature in SQL Server 2012. These are columnar indexes
optimized for blazing fast performance. Although these indexes will be read-only, partitions may be
switched in to columnstore indexes.

When Is a Table Big Enough to Partition?


After covering the basics of table partitioning, this is usually the first question people have: Is my
table big enough? My response is: Lets talk about why youre interested in table partitioning. What
is the problem youre experiencing?

Tell Me Where Your Table Hurts


When people investigate table partitioning in SQL Server, usually theyre having a problem scaling
up their database. What you are experiencing may take many different forms. The problem can
contain one or more of the following:

Slow queries that return small amounts of data

Slow queries that return large amounts of data

Slow loading of data

Blocking between readers and writers (inserts or updates)

Long-running index maintenance jobs (or an inability to run them at all because
they would take so long)

Slow is of course highly relative. Here it means my users are complaining or my webserver is
timing out or something is failing and paging me in the middle of the night. Often, the tables in
question are being used for a mixture of OLTP activity and reporting activity.

My approach is to talk to the team and find out what the experience of the problem is like. Literally,
What keeps you up at night about this table?

How Is Your Overall Health?


Prescribing table partitioning is like recommending significant surgery you dont want someone to
go under the knife unless its the best way to make things better. I look at the overall health of the
system. Where are the current bottlenecks? What are we waiting on? How healthy are the individual
components? How are the queries currently performing, and what do the query plans look like?
What patterns are in use in the queries which are running? I also look at the structure of the tables
and indexes in the context of the queries.

What Performance Characteristics Do You Need?


How many records do you want to load a day? How many records will you be deleting a day in six
months? How many new clients is your business expecting to be bringing on, and what is the
estimated impact that will have on reads and writes on your system? The number of expected clients
can be tricky to translate to database activity. A SQL Server health check can produce some metrics
for current activity that can be used for projections.

Hows The Health of Your Budget?


Table partitioning isnt cheap this feature is not available in SQL Server Standard
Edition. Further, were losing the option to have CAL-based licenses for Enterprise Edition with SQL
Server 2012. In some cases, Enterprise edition is already in place because of other feature
requirements. In others, budgetary constraints make looking at non-Enterprise features attractive.

How Many Queries Can You Tune?


Whether or not you have the flexibility to tune queries is a big differentiator in how you choose to
scale up your application. On the one hand, table partitioning is transparent because the name of
the partitioned objects doesnt change. On the other hand, you want to tune queries to get partition
elimination and the best possible query plans after you partition and sometimes you need to get a
little creative. The structure of your tables and how queries are currently written will play a huge role
if you have a limited (or no) ability to tune queries.

Whats The Best Approach to Scaling Your


Application?
Heres my secret: I dont answer the question of Should I use table partitioning? Instead, I answer
the question What is the best way to scale this application?
The right approach for your scalability problem may contain table partitioning perhaps by itself,
perhaps in combination with other technologies. In the right application, table partitioning can be truly
awesome. But we also may be able to scale your application up in another way perhaps more

cheaply, perhaps more quickly, or perhaps in a way that includes built-in geo-diversity. It all depends
on your database health, performance requirements, budget, and flexibility.

Still Interested?
If you got this far and youre still interested in table partitioning, maybe its the right fit for you!
Before you start designing a table partitioning strategy, or if youre trying to troubleshoot why your
partitioned tables arent working as fast as you expect, check out our SQL Server table partitioning
resources page.
Related

Temporal Tables, Partitioning, and ColumnStore Indexes


In "SQL Server"

[Video] Office Hours 2016/10/19 (With Transcriptions)


In "SQL Server"

Partitioned Views: A How-To Guide

In "SQL Server"
2 289

Kendra Little
My goal is for you to understand your SQL Servers behavior and learn how to change it. When Im not
figuring out the solutions to your database problems, youll find me at user group meetings in Portland, Oregon.
I also love to draw.

PREVIOUS POSTWhy Availability Groups Make It Cool Again to Be a SysadminNEXT POSTSQL

Server 2012 Release Date: April 1, 2012

130 comments. Leave new


Oscar Zamora
March 6, 2012 8:29 am

There are application implications when a large transcriptional table is partitioned. The unique key is
now partitioned align, and unique index calls and foreign key relationships need to include the
partitioned aligned column. Even worse, you can no longer guarantee a unique identifier on the table
just by itself, unless the unique identifier is the only unique index and is also the partition scheme.
However, most partitioning strategies involve date+timestamp in order to exercise sliding window.
I wish SQL Server enhanced their partitioned tables to include Global Indexes, like the ones
supported in Oracle for over 10 years now. It would be completely transparent for the application.
Reply

Kendra Little
March 6, 2012 12:32 pm

For readers who are new to partitioning, I would just add that you can make a unique index which
doesnt include the partition key but that index is non-aligned with the partitioned table.
Having one or more non-aligned indexes enabled on a partitioned table means that swapping
partitions in and out no longer works. And thats one of the biggest features of partitioned tables, so
thats a bummer!
This is where people get into the really hard choices when they implement partitioning on databases
that serve an OLTP role, or a mixed OLTP role. I dont personally think thats always a bad idea it

really depends on the use case and looking at all the options but there typically arent nearly as
many hard choices to make when it comes to reporting/ warehousing style of databases.
I expect to see partitioning usage increase with columnstore indexes becoming available. its
definitely going to be interesting!
Reply

Oscar Zamora
March 6, 2012 9:31 pm

For EDWs and Data Marts the implementation of partitioning is a no-brainer. Staging to table to
partition switch-in is one of the best methods of appending data to the facts. Same goes for sliding
windows for data archival.
Going back to OLTP, I have come across solutions that loaded in excess of 20 million rows per table
per day that were part of well normalized schema. The application was making calls that read any
rows of those table for the last N days. Because our backup windows increased and due to the fact
that storage was limited, we needed to re-architect to support partitioning on these tables. It was a
challenge, but once in place it made data archiving an easy task, and allowed us to tier the storage
for Read-Only filegroups/partitions. Backups windows decreased as it was only taking care of ReadWrite Filegroups.
Partitioning for column-store indexes are a must IMO. It will allow the DBA to create them on a
staging table before switching in into the master table. Columnar-store indexes are not updatable as
you already know, and any addition to the master table via DML will require a drop and recreation of
the column-store index. Not ideal when you have billions of rows.
Reply

Peter Maloof, the OCD Proofreader


March 6, 2012 9:12 am

Kendra:
Thanks for the good partitioning overview.
Should The Froyo DBA team needs to maintain only 13 of data in the FroyoSales table. be The
Froyo DBA team needs to maintain only 13 months of data in the FroyoSales table.?
Reply

Kendra Little
March 6, 2012 12:28 pm

It absolutely should! I made the correction. Thanks for letting me know.

Reply

zack
March 7, 2012 1:01 am

how partitioning table can solve read write lock issue you described in An Textbook Example, can u
be more specific ?
because as far as i know insert operations basiclly dont block reads(on increasing clustered index),
update operations block reads with key lock but same story after partitioning .delete operations wont
block reads either if you avoid lock escalation.
Reply

Kendra Little
March 7, 2012 9:32 am

Hi Zack,
Partitioning doesnt change the behavior of isolation levels. The trick is that when youre loading data
into the staging table, none of the reports are reading from it yet that staging table is completely
separate. The only issue with locking youre going to hit on the partitioned table is when you switch
in. That requires the schema modification lock, so there could be blocking there but it is one small,
atomic, fast operation.
Hope this helps.
Reply

Regu
March 8, 2012 11:46 pm

Kendra: Excellent Article, for our oragnization database we were thinking and few discussions
whether or not to go for Partitioning, this article helps
Reply

KC
March 10, 2012 3:22 pm

Kendra what are the plusses and minuses to using Hash partitioning on OLTP tables with large
numbers of inserts on a daily basis?
Reply

Kendra Little

March 13, 2012 3:11 pm

Hi KC,
This is a great question and the answer could be considerably lengthy. I think itll make a great blog
post. To give the biggest picture one-size-fits-all-schemas/apps answer, the first thing I would think
about is this:
What are the application requirements in terms of reading? When Im partitioning data, I have to pick
a partitioning key. If speed of targeted reads is critical as well, then I will need to have a meaningful
key that I can identify quickly and use to do partition eliminations on my reads. So, depending on
what I need to do with the data after I write it, I may have a lot to consider there.
Other things to consider are just how many writes you need to do over time. If were talking table
partitioning alone, were talking about tables in the same database. That means we only get one
transaction log file, and theres only ever going to be so much we can do with one log, for example
logs have limits. But before we ever get to that limit, we might hit limits with our storage, with our
processor power, etc all depends on that hardware.
So, long story short, things like this are why I like to step back and say, What are our eventual
goals? and really dig into what the application needs to do and work from that direction. I might end
up at a solution involving table partitioning, but I might end up with other designs as well.
Thanks for the great comment thats a really rich question and considerations for pros and cons
there will make a great post. Stay tuned.
Reply

Marius
October 11, 2012 8:53 am

Hi Kendra,
You said in your article that You want to be careful about splitting partitions performance can be
very slow. That is definitely true and I find myself confronted with this problem, having to extract one
year worth of data from a yearly partitioned table that hasnt been maintain (and now the last
partition contains 3 years instead of one). Is there anything that can be done to speed up this
process? Would shrinking and / or reorganizing the filegroup before starting the split help? How
about compressing the partition before the split?
Thanks
Reply

Jim
January 22, 2013 12:12 pm

How about dribbling the rows out, say 1 or 2% a day? If the table hasnt been maintained for 2 years,
another month or two shouldnt kill you.
Reply

Inbar Katz
November 8, 2012 8:05 am

Kendra, do you know about cheaper alternatives for partitioning other then upgrading to the
expensive Enterprise Edition?
I hear about Rewius (www.rewius.com) which claim to provide partitioning on Standard Edition
database, Do you have experience with their software?
Reply

clark vera
June 2, 2013 10:28 pm

I did this once very effectively in sql 2000 simply by creating an archive table. I copied the last 90
days worth of data into a new table with the same structure, then I renamed both tables, the old one
was now called DataArchive, and the new one renamed DataCurrent. Then I just had sql agent
move the daily records every night into the archive. The queries had to be modified to query current
and archive records with a UNION, but I wrote SQL stored procedures to handle it automatically.
worked great for a long time.
Reply

Brent Ozar
June 3, 2013 5:23 am

Clark you can make your life even easier by checking out partitioned views.
Reply

Muktesh
January 4, 2013 2:05 pm

Performance is very important with any application.If your database tables have millions of records
then a simple SQL query will take 3-4 mins.but ideal time for a query should be at max 5 sec. Now
the Question comes How can improve performance with large databases.
See this article http://techathon.mytechlabs.com/performance-tuning-while-working-with-largedatabase/
Reply

Kendra Little
January 4, 2013 2:56 pm

Its funny performance is important with the databases we get called in to look at, but theres lots of
databases where its not a big deal. I also find that a few million rows is pretty small change these
days!
Reply

Muktesh
January 4, 2013 2:07 pm

Table partitioning is best way to improve database performance with large databases.If your table
contain millions of records then this is highly recommended you should use partitioning.In this article,
I will explain what is partitioning and how can implement partitioning with database.
see: http://techathon.mytechlabs.com/table-partitioning-with-database/
Reply

Kendra Little
January 4, 2013 2:53 pm

I cant disagree with your leading sentence more. Table partitioning can also be the best way to
DESTROY application performance in large databases. Please keep that in mind.
Reply

Zakaria
August 20, 2013 8:18 am

Hello Kendra,
Could you tell us a bit more about how partitioning could destroy application performance in some
cases. Do you mean by that too much partitioning ?
Thank you.
Reply

Kendra Little
August 20, 2013 4:10 pm

Hi,
I mean just because of the partitioning itself. Table partitioning is a pretty complicated thing for SQL
Server to handle and it changes query optimization and join strategies.

Check out this blog post by Paul White one some query issues involving a partitioned table. This is
just one example, but it shows how complex it can
be: http://sqlblog.com/blogs/paul_white/archive/2013/06/17/improving-partitioned-table-joinperformance.aspx
The worst situation is when people dont expect that partitioning can hurt performance. They
implement it, then application performance gets slow. People then have the task of figuring out if the
table partitioning is the cause of the performance problem (in part, or in whole), or is just a
bystander, and its a very tough situation. So definitely tread with care.
Kendra
Reply

Zakaria
August 21, 2013 10:10 am

Ok so i understand that theory is not enough is table partitioning. Execution plan analysis and maybe
some modifications in the queries are required to reach the best performance.
Thanks.
Kendra Little
August 21, 2013 11:42 am

Yes, exactly! Heres another interesting example its a Connect Item called Partition Table using
min/max functions and Top N Index selection and performance. The workarounds tab gives some
examples of the kinds of rewrites that might be needed.
http://connect.microsoft.com/SQLServer/feedback/details/240968/partition-table-using-min-maxfunctions-and-top-n-index-selection-and-performance
Jeff Moden
August 10, 2013 11:19 am

I agree with Kendra. Contrary to what many believe, Table Partitioning is absolutely NOT the best
way to improve database performance unless each and every query is setup to take advantage of
the partitioning column. For example, if youve partitioned an audit table by month on the
DateCreated column, then the only way that a query can take advantage of the partitioning is if the
WHERE clause has a date range criteria for the DateCreated column. If youre searching for
something else, then youll be searching across all months and partitioning isnt going to help at all.
Instead, you need a good index to support the query and you need well written code thats actually
capable of using the index properly just as if the table werent partitioned.
To wit, partitioning is hardly ever done for reasons of performance of code. Rather, partitioning is
done to ease backup requirements (especially if static partitions are set to ReadOnly), allow for
Piecemeal Restores, and to make index maintenance take less time and require fewer resources

because you can rebuild/reorg the indexes by partition and then only on those partitions that actually
need it.
If you want better performance, design better tables, design better indexes, and most importantly,
write better code. Partitioning alone just isnt going to do it for you and then itll help only in very
specific cases depending on the partitioning column youve chose.
Reply

Jeff Moden
August 10, 2013 11:27 am

Sorry, one thing to add.


Partitioning can help performance by spreading the load out across multiple disks. Anytime you can
get more spindles and their separate read-write heads involved, you will usually see some
performance improvement. That doesnt happen very much, nowadays, because a lot of SANs
recommend that you let the SAN handle such things. Even on SANS where you can assign logical
disks to particular physical disks, most SAN manufacturers recommend that the SAN will be able to
do a better job than such manual setups would do or the SAN administrators just dont want to do
such a thing.
As a bit of a sidebar, its almost a shame that hard disks have gotten so large because you used to
be able to get a whole lot more spindles/RW heads involved than you can today.
Reply

Developer
January 7, 2013 5:07 pm

You guys talk about partitioning a data warehouse fact table and using partition switch to load data
into it. Almost always fact tables are loaded daily in a datawarehouse. Is that common to partition the
fact table by day to be able to using switching?
Reply

Kendra Little
January 7, 2013 6:12 pm

Yep, a day is a common choice for the partitioning grain. The version of SQL Server will impact the
number of partitions you can have at a given time. Originally only 1,000 partitions were allowed in a
partitioned object.
As of SQL Server 2008 SP2 / SQL Server 2008 R2 SP1 and higher versions, there is support for
15,000 partitions per object, but it needs to be enabled.

So basically, yes, daily is common, but if you need to keep more than 1,000 days then you may
require some special configuration. (Although of course that could be true at other grains as well.)
More info is here: http://msdn.microsoft.com/en-us/library/gg981694.aspx
Reply

Developer
January 7, 2013 7:37 pm

For a multi fact table data warehouse, if each partition is stored in its own file group with at least one
file, wouldnt that create thousands of data files for the database? It sounds kind of scary

Reply

Kendra Little
January 7, 2013 7:41 pm

If you followed that recipe, you could indeed end up with thousands of data files and in turn that
could create some very slow startup times for your database.
You have options about where you want to put your partitions. Many partitions can be mapped to the
same filegroup (and a filegroup can have one or many files). You could go to the other extreme and
have thousands of partitions all on the primary filegroup on a single file, too. All those partitions could
be from one or more partitioned objects.
The partition scheme is where you map out how the partitions are laid out on filegroups. And it can
certainly be tricky to figure out whats going to perform best in an environment, depending on how
the partitions are used and what kinds of storage you have available.
You can have more than one object share a partition scheme, by the way its pretty flexible which is
great but it makes the choices complex!
[Edit: added a couple more details about all the options]
Reply

Developer
January 8, 2013 12:21 pm

You mentioned that having many file groups/data files will impact database start up. Is that the only
disadvantage? What are some of the advantages of having multiple file groups when doing
partitioning or even having one file group per partition. I say that because most examples I have
come across, the table is partitioned by month and each month is stored in its own file group. The

one advantage I see in that is the fact that you could make older file groups read-only and reduce
backup times. Is that the only advantage?
Kendra Little
January 8, 2013 12:32 pm

Storage cost and performance also factor in. Often only the more recent portions of data are queried
regularly ideally Ill keep those on faster storage. Much older data may need to be online, but if
storage costs are an issue I might want to keep that on cheaper, slower storage.
Depending on what type of storage is in play, getting this all to work without having lots of downtime
can be tricky, but there are some cool tricks if youre using a SAN or virtualization. (And sometimes
having a bit of downtime on parts of the data to get this done is perfectly fine, too.)
Filegroups also allow more benefits/options when it comes to backup and restore. If my older
partitions are not actively being written to, I can mark their filegroups read-only and then back them
up more infrequently thereby reducing space, time and resources needed for backups.
All of this stuff adds complexity on the DBA side to make sure that youre still getting the perf you
need and that backups are being done properly. But it can be very cool.
Edit: I should say that the startup time issue with lots of files does take a bit of work. Were not
talking about 20 files causing that issue. On most production sized boxes its going to be thousands
of files (across all the databases). But it can definitely happen.
Developer
January 8, 2013 1:27 pm

Thanks for the quick reply Kendra, much appreciated.


So basically, the solution will really depend on specific requriments. Here is what we are looking
at

We have multiple large fact tables in our data warehouse (over 100 GB each)
We need to apply a retention policy and drop/archive old data
We load fact tables daily
The retention could be applied monthly or quuarterly
We are hoping to reduce the backup window and index management tasks
at a high level what sort of design would you recommend in terms of partition grain and number of
filegroups/files. Based on your previous comments I was thinking of partitioing by day to improve
loading of fact tables and creating monthly file groups for each fact tables so that older file groups
could be marked as read-only therefore helping the backup process. In terms of retention, if it is
done every month, we would need to switch all daily partition within that historical month to staging
tables and drop/move them.

Reply

Kendra Little
January 8, 2013 1:43 pm

Theres just so much that goes into it that theres no way I can make a recommendation based on a
conversation or blog comments. I would want to start off before the assumption that table partitioning
is the right fit here there might be a different schema option that could work and be better for
licensing and support.
I certainly dont mean to blow off your question in any way. This kind of architectural
recommendation is something that typically takes a multi-day engagement to make because of all
the factors that are involved.
Reply

Developer
January 8, 2013 1:55 pm

No problem. Thanks anyways!


Reply

Developer
January 8, 2013 10:32 pm

Hi Kendra,
One general question about file groups when table partitioning is implemented: is it common to
create/drop file groups and files dynamically using scripts which maintain table partitions? In other
words are file groups normally pre-created and maintained when needed or dynamically created and
dropped by scheduled scripts when new data comes in?
Reply

Kendra Little
January 9, 2013 4:40 pm

Most people pre-create a certain amount of partitions, and have an automated process that regularly
checks and pre-creates more. That way if for some reason the process doesnt run for a while you
dont end up with a bunch of data in the wrong place.
Reply

Jim
January 22, 2013 12:15 pm

Where have you posted your helper functions for partitioning? They look very useful.
Reply

Kendra Little
January 22, 2013 12:23 pm

Hi Jim!
Glad the views look good!
Those will get posted with the video from todays webcast. Look for them later this week. (Im my
own Audio Visual team and processing the video takes a little time.)
Ill link everything up from our master partitioning page http://brentozar.com/go/partitioning when that
goes live, too.
Edit: I originally wrote functions instead of views. Maybe that coffee was TOO good this morning.
Reply

David Eaton
January 28, 2013 1:39 pm

Hey Kendra,
Nice blog, but I got a question for you.
Would you start with partitions in place if you know that your data is going to grow faster than you
can respond?
The system I am working on has the potential to grow into the Terabyte size in less than a year.
It is a Mulit-Tennant system where the main partition key would be the CompanyID. That would
then exend into customer and orders etc. And this is a transactional system.
Just wonder what you think of this situation?
Thanks!
David
Reply

Kendra Little
January 29, 2013 9:27 am

If your partition ID is CompanyID and you say its a transactional system, Im guessing that youre
not implementing table partitioning for switching (loading data externally and moving in a whole
partition quickly / moving a whole partition out quickly).
If this is the case and youre trying to partition for performance, I would step back and examine if its
really the best fit for you architecturally. There may be other designs that accomplish your goals
without making performance tuning so difficult over time. I would factor in not only application
performance, but also RPO, RTO, and scalability across servers/licensing over time into the
decision. There are lots of other options, many of which dont lock you into EE on every SQL Server
instance (including DR), and which might address your problems.
But I absolutely agree that if you know data is going to grow fast, its important to ask these
questions early on! I would just recommend evaluating lots of different options than table partitioning
since its such a tricky beast for performance in OLTP.
Reply

David Eaton
January 29, 2013 10:10 am

Hi Kendra,
Thanks for the response. I realize there are other methods. I am more in favor of distributing the data
via filegroups and better indexing. The reason to look a partitioning is that the may be up tp 8,000
concurrent users from 15000 companies. Each of those companies may have large volumes of data
in key tables. And we are tied to a response time SLA to populate the screen content.
This is a Medical office type application on the cloud. Something like the appointment table can have
hundreds of million rows. Other tables are as large or even larger.
My original plan was to have the application read from a Data Mart and have all transactions pass
through a separate OLTP process server that would valifdate the transaction and then pump it into
the data mart.
Then the idea came up for partitioning the tables for faster select perfomance from the data mart
came into the discussion. I still am not convinced, as you arent, that we should partition, but I have
to chase the idea down and see.
While we are currently still on SQL Server 2008 R2, it occurs to me that moving to 2012 with the inmemory capability would be a better solution. But maybe not.
David
Reply

wattyjnr
February 25, 2013 11:30 am

Hi Kendra,
I have a database that is taking up approximately 66% of space on a network drive that also hosts
other databases. The culprit is one table which is currently 40GB in size. I was considering table
partitioning as a solution to archive off some of this data onto a different file group with more space
available. The table is primarily used for reads. The data is to be retained, so I dont really have the
option of purging historical records. If I have understood things correctly, am I correct in saying table
partitioning would be a reasonable solution in this instance?
Thanks.
Reply

Kendra Little
February 25, 2013 11:42 am

Id step back and take a really hard look at what problems youre trying to solve whether its
performance, backup and restore, or manageability. There are ways to solve problems in all of these
areas without using table partitioning that are much simpler to manage in the long term than table
partitioning and also dont necessarily come with the Enterprise Edition requirement. Id definitely
evaluate all the options, especially for a table as small as 40GB. Thats not very large by modern
standards, really.
Reply

wattyjnr
February 25, 2013 11:49 am

Thanks for your prompt response Kendra. The problem I am trying to resolve is to find a way of
managing the growth of a database, which is taking up a lot of space on our existing server. Not
worried at all about performance, back up/restores etc at this current stage. We have Enterprise
Edition in our Live environment, which is why I was initially considering this option. Do you mind
suggesting any alternative as opposed to the perceived sledge hammer approach I was
considering? Thanks again.
Reply

Kendra Little
February 25, 2013 11:58 am

Sure. If the database is important and I wanted consistent performance, Id consider moving the
whole thing to alternate storage. Id also look hard at the table and indexes and identify how much of
that space may be in unused or duplicate nonclustered indexes there might be a way to reduce
the space significantly just by adjusting your indexing.

You do have the ability to move entire tables or indexes to a new filegroup without partitioning them.
Just be careful mixing storage sources if you need to ensure consistent performance. That holds true
whether or not youre using partitioning, of course.
If youre open to EE features, you could also look at data and row compression. Like Table
Partitioning, using these features means that you cant restore a backup to a Standard Edition
instance, which can sometimes impact DR, so just include that in your planning if any of the EE
features turn out to be the best solution.
Reply

wattyjnr
February 25, 2013 12:08 pm

Excellent!! Thanks for those recommendations. Will use you sp_BlitzIndex to check now!

Brian Bentley
August 22, 2013 4:01 pm

Can you do online rebuilds of individual partitions in SQL Server 2012?


Reply

Kendra Little
August 22, 2013 6:29 pm

This is a great question. Its a great question partly because Im pretty sure this isnt answered in
Books Online anymore (I looked and couldnt find it in the likely places), and I actually thought this
feature had made it into 2012. I was sure Id tested it, and it worked. But I was wrong.
In a test database on SQL Server 2012 against a partitioned table named dbo.OrdersDaily, this
command:
alter index PKOrdersDaily on dbo.OrdersDaily REBUILD partition=5 with (online=on);
Returns:
Msg 155, Level 15, State 1, Line 1
online is not a recognized ALTER INDEX REBUILD PARTITION option.
Online rebuild works for the entire index, offline rebuild works for the partition.
The good news is this is promised for 2014
RTM: http://blogs.technet.com/b/dataplatforminsider/archive/2013/08/16/improved-applicationavailability-during-online-operations-in-sql-server-2014.aspx

Reply

Brian Bentley
August 23, 2013 8:23 am

Thanks for your answer, Kendra. I had looked in the Books Online and was unable to find anything
either.
Reply

Saby
August 31, 2013 2:03 am

Hi Kendra,
If this is the case then there is no use of partioning indexes.
I m having an application where on daily basis 3 GB of data gets inserted.Also in one table we are
having more than 130+ cr of records.should i partition these tables as data gets inserted 24* 7 in
these tables.
Reply

Kendra Little
August 31, 2013 2:53 pm

Im not sure what you mean by if this is the case. There are certainly great uses for table
partitioning its just not a magical performance enhancer that works no matter how your application
is written. It *can* be used to solve real problems when its a good fit for the problems and the right
steps are taken to implement the feature.
Theres no way that I or anyone else can tell you if partitioning would be beneficial for your app
based on 50 words in a blog comment. Its not always good or always bad or definitely helpful
based on any specific amount of data sizes or rowcounts.
Reply

Kyle Dooley
September 6, 2013 11:26 am

I just ran into a very interesting situation upgrading from SQL 2005 to SQL2008R2 with a partitioned
table. A query I wrote to test the new servers performance brought the 2008 server to its knees while
the 2005 server handled it fine. As it turned out it appears to be in the way 2008 handled the query
with the partitioning. 2005 Scanned each partition one at a time then put it back together wile 2008
processed it as one item. This was over my head I had no idea but someone gave me a hand with it
as I was not sure at all what was going on.
http://technet.microsoft.com/en-us/library/ms345599%28v=sql.105%29.aspx

Reply

AJ
September 27, 2013 3:02 pm

Hi Kendra,
I have a requirement to load a very large flat file into the SQL Server tables. I am considering the
technique to load the data into smaller temp tables and then partition switching them into the main
table. My query is how would the SSIS (or any other tool) know what data to load into a particular
temp table. For ex., if I create a temp table in a filegroup only to hold customers from ID 1000 to
2000, then how can I make sure that one instance of SSIS will load only that data into the table while
other instances are loading data to other partitions?
Thanks
Reply

Brent Ozar
September 27, 2013 3:03 pm

SSIS wont know that, actually. Thats up to you to code.


Reply

Kendra Little
September 27, 2013 3:04 pm

Hi there,
When you create a staging table, it has an independent name. You have to code whatever
application thats loading data to know the proper name of the staging table, and also code any
validation checks to make sure that data is going to the right place.
Kendra
Reply

AJ
September 27, 2013 3:34 pm

Hi Kendra & Brent,


Thanks for the response. My problem is we have a single very large file with all of the data. Now if I
have to create temporary staging tables to hold different parts of the data (based on the partition
scheme I choose) I would also like to run the SSIS to load all the temp tables in parallel. This means

I have to use a conditional split so a particular instance loads only that data which should go into the
temp table it is hitting. Is this not a performance hit? Is there a better way to handle this?
Thanks
Reply

Kendra Little
September 27, 2013 3:42 pm

Hey there,
Terminology may be holding us up. You can take a big heap and move it onto a partition scheme by
creating a clustered index on the table on the partition scheme. This can be useful for initially
creating a partitioned object. You could also get really creative and do this when loading data and
switch partitions from table to table.
Now, whether this is advisable or not due to performance is something were not going to be able to
cover in blog comments and the same for which way to load the data is best. Its just way out of
scope for what we can do here.
Kendra
Reply

Jeff Roughgarden
October 7, 2013 5:51 pm

Great article! Thank you!


We are thinking of implementing a three-tier storage solution for an OLTP table that currently has
over 2.2 billion records and over 1 TB of data. Todays transactions would go into non-partitioned
tblTranToday housed in 1.ndf on a RAID 10 SSD-based SAN LUN. The next 18-21 months would go
into tblTransCurrent and be housed in 2.ndf on a RAID 10 HDD-based SAN LUN. The next 4*M
quarters + N years would go into tblTransArchive and be housed in 3.ndf on less expensive RAID 50
HDD-based SAN LUN. All three ndfs would be in the same secondary file group. In the early
morning, the previous days transactions would be moved (via inserts and deletes in batched
transactions) to tblTransCurrent. On the first day of each month, a job would merge the daily
partitions of the prior month. Every three months, the job would also merge the oldest three months
into the prior quarters partition, and switch it to tblTransArchive.
My question (at last) is: Will this quarterly switch work across files in different LUNs? They are in the
same file group, per requirements, but I dont see how the switch can occur via meta-data alone,
since the data is in physically different LUNs.
Reply

Kendra Little

October 7, 2013 6:18 pm

Hi Jeff,
You are exactly right for partitioning switching, source and target must be on the same filegroup! A
good little summary of the rules is here: http://technet.microsoft.com/enus/library/ms191160(v=sql.105).aspx
For the portions of the data on SAN storage, its theoretically possible that pieces of data could be
migrated at the SAN level from faster storage to slower storage. However, in reality that requires a
huge amount of coordination between multiple teams and is tricky to automate so its not something
that I find people are really able to do as a regular process.
There is also no shortcut to what youre trying to accomplish with backing up and restoring
filegroups it just doesnt work that way.
This is very big picture, but in your situation itd be worth evaluating whether you can put the archive
data into a separate database (read-only when not being updated, and in the simple recovery model)
with its own backup plan, and potentially work partitioned views into the mix to keep individual tables
reasonably small.
Kendra
Reply

Jeff Roughgarden
October 8, 2013 10:27 am

Hi Kendra,
Thank you for your prompt response!
I realize now that what I was trying to do simply wont work. I had forgotten how files within a
filegroup work. You cannot specify that the hot table goes exclusively on the ndf on the fast storage
and the cold tables on the ndf on the slow storage. It just doesnt work that way. Essentially the
multiple files in a file group allow you to make a poor mans striped RAID. If I had an ndf in each of
three physical storage devices, my three tables would be spread across the three storage devices,
which of course is not the trick I had intended. But I think that even if it were possible to store entire
tables in their own ndfs and put all the ndfs in a single filegroup, it wouldnt make sense to quickly
switch partitions between files on different storage devices.
Reply

Sagesh
October 10, 2013 9:20 am

Hi Kendra,

We are planning to implement the partition in our application.


In the application we have related data stored in multiple tables (around 7 tables) all the tables are
having running number as clustered index.We are planning to create a new column called Partition
Id (1,2,3,4,5 etc) in all the related tables , will create partition tables based on that partition id and
that the related tables will also have the same partition ids so that we can fetch all the related data
from same partition table.
Our application will have more than 25-30 concurrent insert/update/delete on a same table.Currently
all our Select/update and delete logic are based on the clustered index. If we remove the clustered
index from the running number(which is our current PK) and make it as the new column (partition id)
will it impact the performance.Will it lock the tables and give timeouts/deadlocks errors?
Reply

Brent Ozar
October 10, 2013 9:31 am

Hi Sagesh. Why not give it a shot in your development environment? Were huge fans of testing out
things like this so you can learn how it works first-hand. That way youll see the exact execution
plans for your own database schemas.
Reply

Sagesh
October 10, 2013 12:31 pm

Thanks Brent for your quick reply.


I have solved the issue by adding Partition column into my existing clustered index.
Previously execution plan was showing Key lookup for the partition column after adding the column
to the clustered index now its coming with clustered index seek.
Reply

Kendra Little
October 10, 2013 9:44 am

Hi Sagesh,
Definitely test things out as Brent said. Id recommend starting with a prototype and then doing a full
sized test before you ever hit production (minimum).
One piece of information that should be helpful to you: Your clustering key must contain the
partitioning key, but it does not need to be identical to it (or even lead with it).

Nobody can tell you in a blog comment what will perform well and wont suffer deadlocks based on a
short description, though youll have to work with it.
Best of luck!
Kendra
Reply

Kyle
October 10, 2013 10:41 am

What I have seen is a massive performance hit with the partitioned tables I have been testing. For
instance if I select top 100 [columns ] from table where id > 22222. order by recorddate Because the
table is not partitioned by the date but by the id, it does a massive costly sort to put it all back
together from the partitions. Recorddate is indexed but by partition Recorddate..
Reply

Kendra Little
October 10, 2013 10:48 am

Yep, Im not surprised. Table partitioning doesnt make queries faster, and it makes them harder to
tune.
This connect bug proves that its not just
you: http://connect.microsoft.com/SQLServer/feedback/details/240968/partition-table-using-minmax-functions-and-top-n-index-selection-and-performance
Reply

Jeff Roughgarden
October 10, 2013 12:26 pm

Hi Kendra,
Im surprised at your statement above that partitioning doesnt make queries faster. I thought it made
some faster and some slower.
Consider the common case of an unpartitioned table (ID, Date, colX, colY) clustered on an identity
PK (ID) If it is later partitioned on Date, clustered on Date and ID (for uniqueness), with a NC PK on
(ID, Date), then queries filtered on Date can be much faster due to partition elimination. Queries
filtered on ID will be a little slower since the DBMS first uses the PK to get the Date and then goes to
the clustered index to get the remainder of the data (colX and colY).
My testing seems consistent with this reasoning. Im getting logical reads 5 30% of unpartitioned
logical reads when queries are filtered on Date. Isnt this what youd expect?

Reply

Kendra Little
October 10, 2013 12:31 pm

If youre not partitioning, you can tune indexes to achieve as good or better query performance and
its MUCH simpler because you dont have to worry about the aligned/non-aligned index mess with
partitioning.
Never partition to make queries faster. Sometimes you can get partition elimination to work for you,
but even getting that to work is often a struggle.
The feature is GREAT for batch data loads / removals. Dont get me wrong. But query performance
and index tuning aint that much fun with it.
Reply

Kyle
October 10, 2013 12:48 pm

Yes it may make some faster and some slower and imagine what it does to my 130GB (data not
counting indexes) table when it forces a full scan. Try building IO to support that.
Reply

Dimple
October 22, 2013 3:24 pm

I have partition table A (it is partition by each day). It has columnstore index.360 day partition
I have partition table A_staging with live data updates. 5 day worth of data(day 361, 362, )
I have UNIOUN ALL view for above 2 table. So BI can do their query.
Question:
While live data coming to staging table can I create columnstore index on only day 361 partition and
switch into table A ?
if not how can you resolve this problem?
is it advisable to create different filegroup for each partition? each partition has atleat 150 GB of
data.
is it easier to backup data if it is in different file group for each partition?
Reply

Brent Ozar
October 22, 2013 4:21 pm

Dimple troubleshooting column store and partitioning is kinda beyond what we can do here on the
blog. Youll want personalized custom advice on things like that, and thats where our consulting
comes in. For help, click on Contact at the top of the site. Thanks!
Reply

learner
January 3, 2014 11:52 am

Kendra,
When the partitioning is in process fora table, can DML operation be performed on that table in
parallel?
Thanks.
Reply

Kendra Little
January 3, 2014 11:54 am

Hi there,
Switching a partition in or out requires a schema modification lock and that means nobody else can
party with the table.
If youre implementing partitioning on an existing object, whether or not it was online for read queries
would depend on a lot of factors but its not going to allow any other schema modifications while
thats going on.
Hope this helps!
Kendra
Reply

learner
January 3, 2014 12:07 pm

Thanks for the quick response.


Per my understanding, if ONLINE = ON is set, then read operations can be performed when
partitioning is in progress but insert/update/delete cannot be performed. Is this correct? Also, does it
hold true for both 2008 R2 and 2012 both?
Reply

Kendra Little
January 3, 2014 12:10 pm

No problems. Quick terminology check what do you mean by partitioning is in progress? Its not
clear to me exactly what youre asking.
Reply

learner
January 3, 2014 12:13 pm

I meant when split, switch or merge operations are in process.


Kendra Little
January 3, 2014 12:18 pm

Got it. All of those operations will require a schema modification lock at some point in the case of
switch it will need a schema modification lock on the source and target tables. Schema modification
(SCH-M) locks are exclusive, and no other operations can happen while theyre ongoing. (Read,
write, other mods, nothing.)
Related fact: Even an online index rebuild (disregarding partitioning altogether) needs an SCH-M
lock at the very end of the operation.
There are some improvements in SQL Server 2014 as to what operations are online and how you
can handle the blocking related to SCH-M locks, but the SCH-M locks are still required. More info on
that is here: http://blogs.technet.com/b/dataplatforminsider/archive/2013/08/16/improved-applicationavailability-during-online-operations-in-sql-server-2014.aspx
Reply

learner
January 3, 2014 12:38 pm

Thanks for a thorough explanation.


I am planning to automate all the partitioning related activities by using scheduled jobs. However, if
an application is accessing (reads or writes) a table to be partitioned then in this case partitioning
related operations (split, switch, and merge) wont succeed (because exclusive lock cannot be
obtained). Is that true? If yes, then what is the best way to coordinate partitioning window with the
applications to allow the partitioning related maintenance jobs to complete sucessfully?
Reply

Kendra Little
January 3, 2014 12:46 pm

Youre very welcome.

Theres no perfect built-in solution to the problem thats why they added those features in SQL
Server 2014 in the article I linked to. (Even those arent perfect, but theyre an improvement!) You
have to code your operations so that you can detect problems as best you can and react to them if
theres extensive blocking when youre trying to work the sliding window.
Typically with adding new empty partitions and switching things in, you can make it very fast once
you get the exclusive lock. But if theres very longrunning transactions, even if theyre using nolock,
you could be blocked for long periods. So your code has to handle it. (Lock timeout and deadlock
priority are tools you can use.)
Not to add extra work, but just because its worth doing: I always recommend adding extra code to
make sure that the partitions splits and merges you automate are touching empty partitions and
arent going to trigger slow, painful data movement, by the way. Theres nothing worse than hitting a
bug in your code and having it cause a really big ugly slow operation.
Reply

learner
January 3, 2014 12:54 pm

I agree. I prefer to keep empty partitions at both ends to avoid data movement as much as possible.
I will come up with a strategy to keep applications informed of when the partitioning jobs are
scheduled to run so that data can be cached for that duration in application and for end user, system
still appear be be online :).
Thanks again.
Satya Sai P
March 7, 2014 1:47 am

I am a DBA looking after a team working on GIS data and I found some good questions and
answers.
Reply

Akella
March 13, 2014 6:39 am

Hi,
I work on a system where we receive & manipulate a lot of files and deliver to the other systems.
Now this system is being re-used for another product and inorder to avoid dependencies of file
delays on the products, table partitioning cocept has come into picture. Is there any other way to
handle the same.
If so , please let me know.
Reply

Kendra Little
March 13, 2014 9:47 am

Its very difficult to recommend (or not recommend) table partitioning based on what someone can
describe in a blog comment its just much more complicated than that.
Completely unrelated to table partitioning: in general, its better to not store files inside the database,
but instead to store pointers to the files.
Reply

Nigel Findlater
September 23, 2014 2:48 am

Hallo,
Could or should this be used in data archiving?
I have a database that imports a large ammount of insurance data into a set of related tables. I will
need to archive this data. In an ideal world archiving would be simply detaching the ndf file. And
Restoring an archive would be simply attaching the ndf file. Is this an advisable approach?
Thanks for a great article
Nigel
Reply

Kendra Little
September 23, 2014 6:25 am

Theres no supported way to back up or detach a single file or filegroup and restore it to a different
database (or a previously restored database thats been brought online and modified). I really wish
that worked!
Reply

Hanno
February 17, 2015 2:47 pm

Kendra,
Nice article, good overview.
However your text about the fact that statistics are maintained for the entire partitioned table or index
is not 100% accurate anymore with the introduction of incremental statistics in SQL2014 if Im right.

Reply

Kendra Little
February 17, 2015 2:53 pm

I can totally see why youd think that. Even with incremental statistics, the entire histogram still only
gets 200 steps. Sorry to burst your bubble on that one. Ben Nevarez has a good article on that
feature here: http://sqlperformance.com/2014/02/sql-statistics/2014-incremental-statistics
Reply

Sunny
March 19, 2015 4:59 pm

Hi Kendra,
Thanks for sharing this article.
We have 8-10 tables which contains 4-6 years of data and application only uses 12-14 recent
months of data. Tables are huge and basically considrered as history tables. Backup and restores
are huge (in TB) as a result. How can table partioniong help in this scenario?
Reply

Kendra Little
March 19, 2015 6:40 pm

It might be able to help backups if they helped you use read only filegroups for large parts of the
data for more info on that see Brents video here: https://www.brentozar.com/archive/2011/12/sqlserver-storage-files-filegroups-video/
Restores are still going to be rough with filegroups.
Partitioned views might allow you to move some of the historical database to another database on
the instance, and back it up/restore it separately.
Reply

Tsahi
April 27, 2015 1:48 pm

Hi Kendra,
I want to use table partitioning on daily basis with transnational replication. My first thought was to
create a daily job to create partition and file group for the following day but according to MSDN:
ALTER PARTITION FUNCTION is not replicated. I came up with two solutions and I wanted your
input:

1. Create in advance a lot of partitions/file groups


2. Create 2 jobs. one for the publisher and one for the subscriber which will create the objects. My
only fear here is what will happen if the job will fail to run on the subscriber. In this case if Im not
mistaken the replication will fail since the tables wont match
Reply

Kendra Little
April 27, 2015 5:06 pm

Hi there,
Both options have some risk even if you create a lot of partitions/filegroups in advance, eventually
you could run out. And its bound to happen right when someone forgets that its even an
issue

Combining replication and partitioning is definitely tricky. It kind of makes sense that its complicated
because they support having different partition schemes on publisher and subscriber (or even no
partitioning on the subscriber, so you can replicate to Standard Edition).
My biggest piece of advice would be to have your jobs that manage the partitioning include a lot of
checks for both the publisher and the subscriber to make sure that everything is in the right state
before it proceeds. It means a lot of coding and extra testing, but because theres no perfect option,
it ends up being needed.
Reply

Kyle
April 30, 2015 3:02 pm

Kendra when your switching out these partitions and I assume you drop your constraints what about
all the related data to these records? What do people do with that ?
Reply

Kendra Little
April 30, 2015 4:07 pm

Oh, its easier than you think. You dont have to drop foreign key constraints for switching.
Here are the rules: Source and target tables must have the same FOREIGN KEY constraints. If the
target table has any FOREIGN KEY constraints, the source table must have the same foreign keys
defined on the corresponding columns, and these foreign keys must reference the same primary key
as those of the target table. https://technet.microsoft.com/enus/library/ms191160%28v=sql.105%29.aspx

Reply

Kyle
May 1, 2015 7:43 am

Thanks for that info and link!!


Reply

Binh Thanh Nguyen


May 19, 2015 1:03 am

Thanks, nice post


Reply

Jeab
June 8, 2015 9:03 pm

I found a new feature that is called Reference Partition on Oracle 11g. Using reference partitioning, a
child table can inherit the partitioning characteristics from a parent table. but i cannot find like this in
SQL Server 2014
Is there an equivalent feature in SQL Server?
Can I switch out partition tables with reference partitioning from parent table to child table (table A
,B,C) ?
Thank you very much
Reply

Abu Elshabab
July 27, 2015 2:20 am

Thanks for this extremely super useful article, yet I have a question please
Im working in a company that cant afford the Enterprise edition, and we have a very big table (at
least this is how I see it) contains 28 million rows with around 20 columns. Querying that table joined
with another couple of tables is really hectic; so I was searching the net to find a way to manually
mimic SQL Server table partitioning, and I found the following:
https://www.simple-talk.com/sql/sql-tools/sql-server-partitioning-without-enterprise-edition/

Although that is a solution, Im wondering if that is an efficient solution, what do you think? I trust
your opinion the most

Reply

Kendra Little
July 27, 2015 10:16 am

Hi Abu,
The simpletalk article talks through partitioned views. Those can still work well, and they do work
with standard edition. The article mentions one limitation with identity columns there are some other
limitations to read up on Kyle just linked to a books online below this comment to check out, and
also mentioned some query considerations.
Frequently if tables *are* suited for partitioning, using partitioned views can be really desirable even
if you have enterprise edition (sometimes in combination with partitioned tables). The member tables
of a partitioned view can have different columns, so if you have a large fact table, for example, and
older years dont have a column that was added more recently, thats OK. You can also use different
nonclustered indexes on the member tables of partitioned views.
So overall, still a very relevant feature!
Reply

Kyle
July 27, 2015 9:05 am

This would be your best way if you have a good column for the constraint.
https://technet.microsoft.com/en-US/library/ms190019(v=SQL.105).aspx
I really dont think your going to gain much from partitioning unless that column for the constraint is
used in most queries. Your developers need to understand it is a well and my experience has been
this is a big issue.
Reply

shaun ryan
September 8, 2015 11:07 am

Hi.

Bit a noob question but Im struggling with it slightly in my head (someone else asked me today).
What happens if you update the clustered aligned index to a value for to a different partition on
different disk.
Presumably if the index doesnt need to re-balance then it will stay where it is until you rebuild the
index?
Not sure why youd do that on mass in large partitioned table! Probably not a case for partitioning or
would need to rebuild the affected partition aligned indexes.
Reply

Kendra Little
September 8, 2015 11:09 am

Not sure exactly what youre asking because the wording is a bit confusing are you asking if you
can move a whole partition from one logical drive to a different one as a maintenance activity?
Or are you asking what happens if you update the partitioning key on a single row so it now belongs
in a different partition?
Reply

shaun ryan
September 8, 2015 11:22 am

Sorry multi tasking.


Say the table has datekey and its clustered index partition aligned by year. If I update datekey for 1
row from 20150101 to be 20141201 and 2015 and 2014 are partitioned onto 2 different filegroups
what happens to that row? does it get moved in the update or just when the partitions are rebuilt / reindexed?
Reply

Kendra Little
September 8, 2015 11:25 am

Ah, I see. If you update the partitioning key and the row belongs in a different partition, it has to
physically move the row immediately. This is processed internally as a delete/ insert.
Heres a longer post on it: http://blogs.msdn.com/b/wesleyb/archive/2008/10/09/what-happenswhen-i-update-my-partitioning-key.aspx
Reply

Shaun Ryan

September 8, 2015 12:01 pm

cool thanks. That was my first intuition but wasnt sure if it just left it until the B-tree had to
reorganise.
R
October 1, 2015 9:08 am

Hey is it Possible to create partition Quarterly for year if there is no Date Column on the table?
Reply

Kendra Little
October 1, 2015 9:11 am

You have to have a column to partition on. Technically, some people do it without a date column, but
in those cases they have an int column thats a surrogate for a date and I suspect thats not what
youre asking about.
Reply

R
October 1, 2015 9:26 am

Thank you Kendra


was just wondering if there is way. so i cant make partition on table for using date if there is no date
or surrogate key available. right ?
Reply

Kendra Little
October 1, 2015 9:27 am

Correct. Think about it this way. You must choose one column as the partitioning column. In this
case, what would you choose?
Reply

R
October 1, 2015 9:29 am

This is the first time i m trying Partition so have no clue right now.

Kendra Little
October 1, 2015 9:35 am

Yeah, it can be tricky. The fact that you have to have one column as your partitioning key is probably
the first thing you wanna learn, so youre on the right track!
Jevan Steele
January 4, 2016 4:08 am

Hi Kendra.
Consider the following scenario :
Tens of millions of new records are loaded into the data warehouse weekly, outside of business
hours. Most queries are generated by reports and by cube processing. Data is frequently queried at
the day level and occasionally at the month level. You need to partition the table to maximize the
performance of queries.
Can you explain what partitioning level you would implement. By day, week or month?
Reply

Brent Ozar
January 4, 2016 4:44 am

Jevan for personalized architecture advice, shoot us an email at help@brentozar.com and we can
set up a consulting engagement. Obviously partition design is a little beyond the scope of something
youd want to do in a blog comment. Thanks!
Reply

Jevan Steele
January 5, 2016 4:57 am

Hi Brent.
Small confession. This was a question on the Microsoft Sql Server exam. The answer was
partitioning by day . I was stumped to find any advice as to how they came up with the answer.
I shall look further.
Reply

shaun ryan
January 5, 2016 5:05 am

Hehe I remember that question.


The vagueness of some of those questions is sometimes quite funny ;at other times frustrating.
Basically the answer is Day because Data is frequently queried at the day level and occasionally at
the month level. Youll get the parallel performance of partitioning across lots of concurrent day
queries. Month perhaps wont be so great but will parallel run that query also however it will need to
bring the results back together to aggregate.
As Brent has eluded real life is a lot complicated than these exams prepare you for. Good luck
with your studies.
Reply

Brent Ozar
January 5, 2016 7:16 am

HA!
Reply

Martin
February 3, 2016 8:30 am

Can you turn off Native Archive partitioning once you start using it.
We have a Database that is using it under SQL 2014 eval and we only need standard SQL but once
we did hte inplace downgrade the DB wont start as the EE feature is in use.
Reply

samo
April 24, 2016 4:05 am

if I just want to increase performance of insertion of data , I will not make any query
is Creating Partitioned Tables a right action????
Reply

Brent Ozar
April 24, 2016 7:12 am

Samo no.
Reply

islam
April 24, 2016 4:28 am

I have a large table with million records and I want to increase performance of insertion and updates
I dont make querys on it .
is table partitions can fit on this scenario??
Reply

Brent Ozar
April 24, 2016 7:12 am

Islam not typically, no. (For reference, a million rows isnt actually all that much in modern relational
databases.)
Reply

NISHANT
May 17, 2016 2:23 am

Thanks for such details and clear explanation.


Just wanted to check on one thing that I am currently updating 45 millions record to the live db
where we have already 3 billions of record taking 25 hrs since it is live db where there are many
other processes are also running. Also sometimes locking issues also kicks in because of other
processes.
Would it be a good Idea to use partitioning for faster insert\update in batch of 1000 records ? I
appreciate if there is any alternative if you could share with us.
Thanks.
Reply

Brent Ozar
May 17, 2016 6:15 am

For a 3-billion-row table, you dont really want to get architecture advice via a blog comment. Thats
where consulting or architecture comes in.
Reply

Carlton
July 29, 2016 5:40 am

Avery good article I especially like the doodles!


But when you say the partitioning key must be part of each of those indexes it seems to imply (to
me at least) that the partition key must form part of the index key in order to allow switching, I dont
think this is the case.
I for one, created a non clustered index on a partitioned table which did not include the partition key
as the index key column, however I did create the index on the partition scheme, so I am able to
perform switch operations on the table.
What I am curious to know is what part of the the index does the partition column really form a part
of? A look in sys.index_columns for that particular index shows the values for partition key column as
0 for key_ordinal as well as is_included_column but the partition_ordinal = 1 (whatever that
means BOL doesnt clearly mention)
Reply

Carlton
July 29, 2016 5:58 am

Nevermind, this technet article answers my earlier question:


https://technet.microsoft.com/en-us/library/ms187526(v=sql.105).aspx
When partitioning a unique nonclustered index, the index key must contain the partitioning column.
When partitioning a nonunique, nonclustered index, SQL Server adds the partitioning column by
default as a nonkey (included) column of the index to make sure the index is aligned with the base
table. SQL Server does not add the partitioning column to the index if it is already present in the
index.
but still doesnt explain why sys.index_columns.is_included_column = 0
Reply

Kiran
October 20, 2016 6:02 am

Hi Brent,
As most of the existing queries filter on current clustered index column, can you please advise on
using an existing clustered index column as partition ID , I know it will be difficult to manage
partitions when a int/ID column is used rather than a dateTime column, but i prefer to go through that
pain rather than affecting current application/query performance by using a DateTime Partition
Column.
Im seeking this advice only after conducting a thorough review on our current database design ,
please share your thoughts on this strategy.
Appreciate your help.

Regards,
Kiran
Reply

Brent Ozar
October 20, 2016 9:54 am

Kiran you nailed it when you said after conducting a thorough review on our current database
design. Thats exactly the kind of analysis Id need to do before giving you schema advice. If youre
interested in consulting, click on Consulting at the top of the page and you can learn more about our
services. Thanks!
Reply

Ken Craig
November 22, 2016 11:28 am

Is there a way to see last update date for each partition. We have a method to see count on each
partition and creation date but as example today I might have 1 million records loading into 11th
month 2016 partition and then I might have 5k loading into 10th month 2016 and then lets say I have
1k loading into 7th month 2016 partition. I want to see a date that shows those 3 partitions had either
records added or updated today. I can store this in my own table like I did for physical partitions
(partition views) but wanted to find out if this is anywhere else in a system table. P.S. I use this for
loading like SSAS I only process those partitions that have changed today.
Reply

Brent Ozar
November 22, 2016 12:10 pm

Ken for questions, head on over to http://dba.stackexchange.com.


Reply

Kristina
December 16, 2016 5:21 am

Hi,
Thank you for a great article. I am not able to view Table Partitioning poster. Could you please fix
the link or share the right one.
Thank you
Reply

Brent Ozar
December 16, 2016 2:17 pm

Thats no longer available, sorry.


Reply

Leave a Reply
Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.

Post Comment

Subscribe

Email*

Give me the:*

Blog posts

Monday Recap - our favorite links

6-Month DBA Training Plan

DBAreactions.com - DBA gifs

Superpowers and free burgers

Subscribe

SQL Critical Care


If your SQL Server is too slow or unreliable, and you're tired of guessing, we'll help.
In just 3 days, we find the root cause, explain it to you, and teach you how to get permanent pain
relief. Learn more and see sample reports.

Archives by Author
Brent Ozar
Erik Darling
Richie Rump
Tara Kizer

CONSULTINGTRAININGBLOGFREE STUFFCONTACT US
Brent Ozar Unlimited 2016 All Rights Reserved. Privacy Policy

Oracle Create Index tips

Search BC Oracle
Sites

Oracle Tips by Burleson Consulting

Search
Home
E-mail Us
Oracle Articles
New Oracle Articles

Oracle Training
Oracle Tips
Oracle Forum
Class Catalog

Remote DBA
Oracle Tuning
Emergency 911
RAC Support
Apps Support
Analysis
Design
Implementation
Oracle Support

Creating Oracle Indexes


Once you have decided you need to create an index you use the create index
command. The command is pretty straightforward as seen in this example:
CREATE INDEX
ix_emp_01
ON
emp (deptno)
TABLESPACE
index_tbs;

This statement creates an index called IX_EMP_01. This index is built on the
DEPTNO column of the EMP table. We also defined the tablespace that the
index should be created in using the tablespace keyword, in this case we
created it in the INDEX_TBS tablespace.
You can create indexes on multiple columns in a table. Say, for example, we
wanted an index on the EMP table columns EMPNO and DEPTNO. This is
known as a concatenated index, and it?s created this way:
CREATE INDEX ix_emp_01 ON emp (empno, deptno) TABLESPACE index_tbs;

Altering Oracle Indexes


SQL Tuning
Security
Oracle UNIX
Oracle Linux
Monitoring
Remote support
Remote plans
Remote services

If we create indexes, there may be times that we will want to change some
attribute of that index, such as where it is stored. Also, sometimes an index
needs to be rebuilt to help with performance. For cases like these, the alter
index command is what we want.
Let?s look at an example of the use of the alter index command:

Application Server
Applications

ALTER INDEX ix_emp_01 REBUILD TABLESPACE new_index;

Oracle Forms
Oracle Portal
App Upgrades
SQL Server
Oracle Concepts

In this example we use the alter index command to rebuild an index. The
rebuild keyword is what tells Oracle to rebuild the index. When we use the
tablespace keyword, followed by a tablespace name, we are telling Oracle

Got

Software Support
Remote Support
Development
Implementation

Consulting Staf
Consulting Prices
Help Wanted!

which tablespace to recreate the rebuilt index in. By default Oracle will create
the rebuilt index in the same tablespace.
The alter index command allows you to rename an index using the rename to
keyword as seen in this example:
ALTER INDEX ix_emp_01 RENAME TO ix_emp_01_old;

In this case we have renamed the ix_emp_01 index to ix_emp_01_old. All of


the data dictionary entries will be changed by Oracle to reflect the new name
(we will discuss indexes and the data dictionary in a moment)

Dropping Oracle Indexes


Oracle Posters
Oracle Books
Oracle Scripts
Ion
Excel-DB
Don Burleson Blog

Sometimes what we create we must destroy. When it?s time to remove an


index, the drop index command is what is needed. The drop index command is
pretty straight forward as seen in this example:
DROP INDEX ix_emp_01_old;

Generate create index syntax


You can punch create index DDL syntax is using the dbms_metadata package,
something like this:
select
dbms_metadata.get_ddl('INDEX',index_name)
from
user_indexes
where
xxxx;

For more information on creating indexes see these articles:

Create Oracle Indexes

Oracle Create Index Tips

Oracle Create Index Script

This is an excerpt from the bestselling "Easy Oracle Jumpstart" by Robert


Freeman and Steve Karam (Oracle ACE and Oracle Certified Master). It?s
only $19.95 when you buy it directly from the publisher here.

KEE
dep
12c

12c
Ava

Free
Rep

BEW
11g
Got

If you like Oracle tuning, you may enjoy the new


book "Oracle Tuning: The Definitive Reference",
over 900 pages of BC's favorite tuning tips &
scripts.

You can buy it direct from the publisher for 30%-off and
get instant access to the code depot of Oracle tuning
scripts.

Burleson is the American Team

Note: This Oracle documentation was created as a support and Oracle


training reference for use by our DBA performance tuning consulting
professionals. Feel free to ask questions on our Oracle forum.
Verify experience! Anyone considering using the services of an Oracle
support expert should independently investigate their credentials and
experience, and not rely on advertisements and self-proclaimed expertise. All
legitimate Oracle experts publish their Oracle qualifications.
Errata? Oracle technology is changing and we strive to update our BC
Oracle support information. If you find an error or have a suggestion for
improving our content, we would appreciate your feedback. Just email:
and include the URL for the page.

Burleson Consulting

The Oracle of Database Support


Oracle Performance Tuning

Remote DBA Services

Copyright 1996 - 2016


All rights reserved by Burleson
Oracle is the registered trademark of Oracle Corporation.

También podría gustarte