Área de Tecnologías de la Información y las Comunicaciones Aplicadas
Área de Tecnologías de la Información y las Comunicaciones Aplicadas Universidad de Murcia
Área de Tecnologías de la Información y las Comunicaciones Aplicadas
ATICA arrow DBCONNECTOR arrow DBA - Particionamiento
21.09.2017
 
 
DBA - Particionamiento Imprimir E-mail

Una tabla Oracle, por defecto, es un sesgmento del tipo TABLE, y un segmento pertenece a un tablespace concreto. Sin embargo, una tabla particionada está formada por varios segmentos (uno por partición/subpartición), de modo que permite separar las particiones en diferentes tablespaces, repartiendo la E/S, y además se puede operar a nivel de partición, de modo que el administrador tiene más opciones a la hora de realizar labores de mantenimiento sobre una tabla; por ejemplo, puede poner offline una sola partición, dejando el resto online, o mover una partición a otro tablespace, sin afectar al resto, etc.

Lo que cuento a continuación está, en su mayor parte, extraído de http://www.dataprix.com/blogs/respinosamilla/particionado-tablas-oracle. y del manual de conceptos de particionamiento de Oracle.

El particionamiento es en gran medida una técnica de optimización que pretende mejorar los tiempos de respuesta de las consultas, así como el mantenimiento de las tablas, y que puede ser especialmente útil en tablas muy grandes. 

Particionamiento de Tablas con Oracle

El particionamiento fue introducido por primera vez en la versión 8 de Oracle para la gestión de grandes cantidades de información, y para facilitar la tarea de los administradores de bases de datos. Dependiendo de la versión de Oracle en la que estemos, tenemos diferentes tipos de particionado disponibles:

Tipos de Particionamiento

Basicamente, el particionamiento se realiza utilizando una clave de particionado (partitioning key), que determina en qué partición de las existentes en la tabla van a residir los datos que se insertan. Oracle también permite realizar el particionado de indices y de tablas organizadas por indices. Cada partición ademas puede tener sus propias propiedades de almacenamiento. Las tablas particionadas aparecen en el sistema como una única tabla, realizando el sistema la gestión automatica de lectura y escritura en cada una de las particiones (excepto  para el caso de la partición de Sistema introducida en la versión 11g). La definición de las particiones se indica en la sentencia de creación de las tablas, con la sintaxis oportuna para cada uno de los tipos.

  • Particionamiento Range: la clave de particionado viene determinada por un rango de valores, que determina la partición donde se almacenara un valor.
  • Particionamiento Hash: la clave de particionado es una función hash, aplicada sobre una columna, que tiene como objetivo realizar una distribución equitativa de los registros sobre las diferentes particiones. Es útil para particionar tablas donde no hay unos criterios de particionado claros, pero en la que se quiere mejor el rendimiento.
  • Particionamiento List: la clave de particionado es una lista de valores, que determina cada una de las particiones.
  • Particionamiento Composite: los particionamientos anteriores eran del tipo simple (single o one-level), pues utilizamos un unico método de  particionado sobre una o mas columnas. Oracle nos permite utilizar metodos de particionado compuestos, utilizando un primer particionado de un tipo determinado, y luego para cada particion, realizar un segundo nivel de particionado utilizando otro metodo. Las combinaciones son las siguientes (se han ido ampliando conforme han ido avanzando las versiones): range-hash, range-list, range-range, list-range, list-list, list-hash y hash-hash (introducido en la versión 11g).
  • Particionamiento Interval: tipo de particionado introducido igualmente en la versión 11g. En lugar de indicar los rangos de valores que van a determinar como se realiza el particionado, el sistema automáticamente creara las particiones cuando se inserte un nuevo registro en la b.d. Las técnicas de este tipo disponible son Interval, Interval List, Interval Range e Interval Hash (por lo que el particionado Interval es complementario a las técnicas de particionado vistas anteriormente).
  • Particionamiento Reference: particiona una tabla del mismo modo en que lo está la tabla a la que apunta mediante una FK, de este modo es muy fácil particionar del mismo modo 2 tablas "maestro-detalle", pues solo tengo que definir el particionamiento en la tabla maestra (la q tiene la PK) y en la tabla hija (la de la FK) usar PARTITION BY REFERENCE. Es nuevo en 11g.
  • Particionamiento System: se define la tabla particionada indicando las particiones deseadas, pero no se indica una clave de particionamiento. En este tipo de particionado, se delega la gestión del particionamiento a las aplicaciones que utilicen la base de datos (por ejemplo, en las sentencias sql de inserción deberemos de indicar en qué partición insertamos los datos). Es nuevo en 11g.

Oracle nos permite definir sentencias SQL del tipo DML haciendo referencia a las particiones. Es lo que llaman nombres de tabla con extension de partición (partition-extended table names). Por ejemplo, podremos hacer un select sobre una tabla particionada indicando en la sintaxis la partición de la queremos que se haga lectura. Por ejemplo:

SELECT * FROM schema.table PARTITION(part_name);

Esto es igualmente válido para las sentencias INSERT, UPDATE, DELETE, LOCK TABLE. Esta sintaxis nos proporciona una forma simple de acceder a las particiones individuales como si fueran tablas, y utilizarlas, por ejemplo, para la creación de vistas (utilizando la vista en lugar de la tabla), lo que nos puede ser útil en muchas situaciones.

Ejemplos de cada tipo de Particionamiento

Particionado Range

El Particionamiento Range requiere que los registros estén identificados por un “partition key”, y el valor de las columnas “partition key” determina la partición a la cual pertenecerá el registro.

CREATE TABLE sales
( prod_id NUMBER(6)
, cust_id NUMBER
, time_id DATE
, channel_id CHAR(1)
, promo_id NUMBER(6)
, quantity_sold NUMBER(3)
, amount_sold NUMBER(10,2)
)
PARTITION BY RANGE (time_id)
( PARTITION sales_q1_2006 VALUES LESS THAN (TO_DATE('01-APR-2006','dd-MON-yyyy')) TABLESPACE tsa
, PARTITION sales_q2_2006 VALUES LESS THAN (TO_DATE('01-JUL-2006','dd-MON-yyyy')) TABLESPACE tsb
, PARTITION sales_q3_2006 VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy')) TABLESPACE tsc
, PARTITION sales_q4_2006 VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy')) TABLESPACE tsd
);

Este tipo de particionamiento es interesante cuando se tienen datos con un rango lógico y que pueden ser distribuidos por este. Ej. Mes del Año o un valor numérico.

Particionado Hash

En el Particionamiento Hash se aplica una función hash a la partition key, y el resultado de dicha función hash determina a qué partición irá el registro. Es una forma automática de balancear la E/S con el particionamiento. En el ejemplo siguiente vemos una definición sin indicar los nombres de las particiones (solo el número de particiones):

CREATE TABLE dept (deptno NUMBER, deptname VARCHAR(32))
PARTITION BY HASH(deptno) PARTITIONS 16;

Igualmente, se pueden indicar los nombres de cada particion individual o los tablespaces donde se localizaran cada una de ellas:

CREATE TABLE dept (deptno NUMBER, deptname VARCHAR(32))
STORAGE (INITIAL 10K)
PARTITION BY HASH(deptno)
(PARTITION p1 TABLESPACE ts1, PARTITION p2 TABLESPACE ts2,
PARTITION p3 TABLESPACE ts1, PARTITION p4 TABLESPACE ts3);

Lo q dice el manual de Oracle del particionamiento hash:

Particionado List

El Particionamiento List fue añadido por Oracle en la versión 9, permitiendo determinar el particionado según una lista de valores definidos sobre el valor de una columna especifica.

CREATE TABLE sales_list (salesman_id NUMBER(5), salesman_name VARCHAR2(30),
sales_state VARCHAR2(20),
sales_amount NUMBER(10),
sales_date DATE)
PARTITION BY LIST(sales_state)
(
PARTITION sales_west VALUES('California', 'Hawaii'),
PARTITION sales_east VALUES ('New York', 'Virginia', 'Florida'),
PARTITION sales_central VALUES('Texas', 'Illinois')
PARTITION sales_other VALUES(DEFAULT)
);

Este particionado tiene algunas limitaciones, como que no soporta múltiples columnas en la clave de particionado, los valores literales deben ser únicos en la lista, permitiendo el uso del valor NULL (aunque no el valor MAXVALUE, que si puede ser utilizado en particiones del tipo Range). El valor DEFAULT sirve para definir la partición donde irán el resto de registros que no cumplen ninguna condición de las diferentes particiones.

Particionamiento Composite

El Particionamiento Composite combina el uso de dos particionados a la vez. Veamos un ejemplo utilizando el tipo RANGE y el HASH. En primer lugar, hace un particionado del tipo RANGE utilizando rangos de años. En segundo lugar, para cada partición definida por cada año, hacemos un segundo particionado (subparticion) del tipo aleatorio (HASH) por el valor de otra columna: 

CREATE TABLE TAB2 (ord_id     NUMBER(10),

     ord_day    NUMBER(2),

     ord_month  NUMBER(2),

     ord_year   NUMBER(4)

     )

  PARTITION BY RANGE(ord_year)

  SUBPARTITION BY HASH(ord_id)

  SUBPARTITIONS 8

   ( PARTITION q1 VALUES LESS THAN(2001)

     ( SUBPARTITION q1_h1 TABLESPACE TBS1,

       SUBPARTITION q1_h2 TABLESPACE TBS2,

       SUBPARTITION q1_h3 TABLESPACE TBS3,

       SUBPARTITION q1_h4 TABLESPACE TBS4

     ),

     PARTITION q2 VALUES LESS THAN(2002) 

     ( SUBPARTITION q2_h5 TABLESPACE TBS5,

       SUBPARTITION q2_h6 TABLESPACE TBS6,

       SUBPARTITION q2_h7 TABLESPACE TBS7,

       SUBPARTITION q2_h8 TABLESPACE TBS8

     ),

     PARTITION q3 VALUES LESS THAN(2003) 

     ( SUBPARTITION q3_h1 TABLESPACE TBS1,

       SUBPARTITION q3_h2 TABLESPACE TBS2,

       SUBPARTITION q3_h3 TABLESPACE TBS3,

       SUBPARTITION q3_h4 TABLESPACE TBS4

     ),

     PARTITION q4 VALUES LESS THAN(2004)

     ( SUBPARTITION q4_h5 TABLESPACE TBS5,

       SUBPARTITION q4_h6 TABLESPACE TBS6,

       SUBPARTITION q4_h7 TABLESPACE TBS7,

       SUBPARTITION q4_h8 TABLESPACE TBS8

     )

   )

Las combinaciones permitidas son las siguientes (se han ido ampliando conforme han ido avanzando las versiones de Oracle): range-hash, range-list, range-range, list-range, list-list, list-hash y hash-hash (introducido en la versión 11g).
Particionado Compuesto


Particionado Interval

El Particionamiento Interval ha sido introducido en la versión 11g para habilitar la creación dinámica de particiones al particionar por rango (RANGE). Normalmente, cuando realizamos un particionado sobre una tabla, indicamos una lista de valores o rangos para crear de antemano las particiones.  Posteriormente, ajustamos la definición de las particiones para incluir nuevas para nuevos rangos o valores. Con el particionamiento Interval, Oracle crea las particiones de forma automática cuando lo necesita. Básicamente, se define un intervalo y una directiva para decirle a Oracle como se tiene que comportar. Veamos un ejemplo:

CREATE TABLE T_11G(C1 NUMBER(38,0),
C2 VARCHAR2(10),
C3 DATE)
PARTITION BY RANGE (C3) INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(PARTITION P0902 VALUES LESS THAN (TO_DATE('2009-03-01 00:00:00','YYYY-MM-DD HH24:MI:SS')));

Hemos creado una partición base, y con lo especificado en Interval definimos como gestionar la creación automática de nuevas particiones. La posibilidad de definir un intevalo y que Oracle se encargue de crear las particiones a medida que se vayan necesitando resulta muy interesante para facilitar el mantenimiento y administración de particiones.

Particionado System

El Particionamiento System es una de las nuevas funcionalidades introducida en la version 11g, y también se denomina particionamiento interno o de sistema. En este particionado Oracle no realiza la gestión del lugar donde se almacenarán los registros, sino que seremos nosotros los que tendremos que indicar en que partición se hacen las inserciones.

create table t (c1 int,
c2 varchar2(10),
c3 date)
partition by system
(partition p1,
partition p2,
partition p3);

Si hicieramos un insert sobre la tabla (por ejemplo, insert into t values (1,’A',sysdate);), daría error, siendo la instrucción a ejecutar correcta la siguiente:

insert into t partition (p3) values (1,’A',sysdate);

Puede ser util este particionado cuando nos interesa particionar en función de la lógica de la aplicación.

Uso de columnas virtuales para particionar

En la versión 11g se pueden definir en las tablas columnas virtuales (no existen físicamente). Ademas estas columnas se pueden utilizar para realizar particionado sobre ellas. La forma de crear una tabla con columnas de este tipo sería la siguiente:

create table t (c1 int,
c2 varchar2(10),
c3 date,
c3_v char(1)
generated always as
(to_char(c3,'d')) virtual
)
partition by list (c3_v)
(partition p1 values ('1'),
partition p2 values ('2'),
partition p3 values ('3'),
partition p4 values ('4'),
partition p5 values ('5'),
partition p6 values ('6'),
partition p7 values ('7') );

Gestión del particionado

Se pueden añadir particiones a una tabla particionada existente, juntar o borrar particiones, convertir una particion en una tabla no particionada, dividir una partición en dos (Splitting), hacer un truncate (borra los datos de la partición pero deja la estructura). También podemos mover una partición de un tablespace a otro, renombrarla, etc. Os recomiendo la lectura del Database Design que también habla sobre el tema.

Enlaces sobre Particionamiento y nuevas funcionalidades en 11g

FAQ

  • No se puede particionar por una columna "timestamp with time zone", da un error ORA-3001 de "funcionalidad no implementada". Sí podremos usar una columna "timestamp" normal
  • Si la tabla está particionada por rango (o intervalos), y nos interesa particionar los índices únicos de forma local, sería necesario que la clave de particionamiento formase parte de ellos. En el siguiente ejemplo la clave de particionamiento es LOGS_FECHA:

create unique index uk_LOGS_FIND on LOGATICA.LOGATICA_LOGS
(LOGS_APLICACION, LOGS_FECHA, LOGS_NIVEL, LOGS_LOUR_CODIGO)
local tablespace indlogatica storage (initial 2M next 2M maxextents 1 pctincrease 0);


Última modificación ( 13.05.2013 )
 
Área de Tecnologías de la Información y las Comunicaciones Aplicadas
Volver al incio del documento Volver al inicio del documento
Área de Tecnologías de la Información y las Comunicaciones Aplicadas