Sei sulla pagina 1di 5

Particiones en MySQL y Oracle

Particiones en MySQL
Particionar tablas en MySQL nos permite rotar la informacin de nuestras tablas en diferentes
particiones, consiguiendo as realizar consultas ms rpidas y recuperar espacio en disco al
borrar los registros. El uso ms comn de particionado es segn fecha (date).
Para ver si nuestra base de datos soporta particionado simplemente ejecutamos:
SHOW VARIABLES LIKE '%partition%';

A continuacin veremos un ejemplo de cmo particionar una tabla por mes y posteriormente
borrar o modificar su informacin.
Crear particiones
1.- Creamos la tabla reports:
CREATE TABLE reports (
id int(10) NOT NULL AUTO_INCREMENT,
date datetime NOT NULL,
report TEXT,
PRIMARY KEY (id,date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Como se puede ver hemos aadido como ndice de tabla el campo date, esto es necesario si
luego queremos particionar por fecha.

2.- Ahora que tenemos la tabla creada vamos a particionar por mes:

ALTER TABLE reports PARTITION BY RANGE(TO_DAYS(date))(
PARTITION p201111 VALUES LESS THAN (TO_DAYS("2011-12-01")),
PARTITION p201112 VALUES LESS THAN (TO_DAYS("2012-01-01")),
PARTITION p201201 VALUES LESS THAN (TO_DAYS("2012-02-01")),
PARTITION p201202 VALUES LESS THAN (TO_DAYS("2012-03-01")),
PARTITION p201203 VALUES LESS THAN (TO_DAYS("2012-04-01")),
PARTITION p201204 VALUES LESS THAN (TO_DAYS("2012-05-01")),
PARTITION p201205 VALUES LESS THAN (TO_DAYS("2012-06-01")),
PARTITION pDefault VALUES LESS THAN MAXVALUE
);


La ltima particin (pDefault) tendr todos los registros que no entren en las particiones
anteriores. De esta manera nos aseguramos que la informacin nunca dejar de insertarse en
la tabla.
Borrar particiones
Lo bueno de trabajar con particiones es que podemos borrar rpidamente registros sin tener
que recorrer toda la tabla e inmediatamente recuperar el espacio en disco utilizado por la
tabla.
Por ejemplo si queremos borrar la particin ms antigua simplemente ejecutamos:
ALTER TABLE reports DROP PARTITION p201111;

Aadir particiones
En el ejemplo anterior las 2 ltimas particiones creadas han sido:
PARTITION p201205 VALUES LESS THAN (TO_DAYS("2012-06-01")),
PARTITION pDefault VALUES LESS THAN MAXVALUE

El problema es que todos los INSERTs que se hagan despus de mayo de 2012 se insertarn
en pDefault. La solucin sera aadir particiones nuevas para cubrir los prximos meses:
ALTER TABLE reports REORGANIZE PARTITION pDefault INTO (
PARTITION p201206 VALUES LESS THAN (TO_DAYS("2012-07-01")),
PARTITION pDefault VALUES LESS THAN MAXVALUE);


En el caso que no tuvieramos una particin del tipo pDefault simplemente ejecutamos:
ALTER TABLE reports ADD PARTITION (PARTITION p201206 VALUES LESS THAN
(TO_DAYS("2012-07-01")));
Consultar particiones
Para consultar informacin de particiones creadas en una tabla as como tambin los registros
que contiene cada una ejecutamos:
SELECT PARTITION_NAME,TABLE_ROWS FROM information_schema.PARTITIONS WHERE
TABLE_NAME='reports';

--------------------------------------------------------------

Por rango: para construir nuestras particiones especificamos rangos de valores. Por ejemplo,
podramos segmentar los datos en 12 particiones: una para los contratos de 1950 a 1960,
otra para los aos 60, los 70, 80, 90, la dcada del 2000 y la dcada actual
view plaincopy to clipboardprint?
1. ALTER TABLE contratos
2. PARTITION BY RANGE(YEAR(fechaInicio)) (
3. PARTITION partDecada50 VALUES LESS THAN (1960),
4. PARTITION partDecada60 VALUES LESS THAN (1970),
5. PARTITION partDecada70 VALUES LESS THAN (1980),
6. PARTITION partDecada80 VALUES LESS THAN (1990),
7. PARTITION partDecada90 VALUES LESS THAN (2000),
8. PARTITION partDecada00 VALUES LESS THAN (2010),
9. PARTITION partDecada10 VALUES LESS THAN MAXVALUE
10. );
Por listas: para construir nuestras particiones especificamos listas de valores concretos.
view plaincopy to clipboardprint?
1. ALTER TABLE contratos
2. PARTITION BY LIST(YEAR(fechaInicio)) (
3. PARTITION partDecada50 VALUES IN (1950, 1951, 1952, 1953, 1954, 1955, 195
6, 1957, 1958, 1959),
4. PARTITION partDecada60 VALUES IN (1960, 1961, 1962, 1963, 1964, 1965, 196
6, 1967, 1968, 1969),
5. PARTITION partDecada70 VALUES IN (1970, 1971, 1972, 1973, 1974, 1975, 197
6, 1977, 1978, 1979),
6. PARTITION partDecada80 VALUES IN (1980, 1981, 1982, 1983, 1984, 1985, 198
6, 1987, 1988, 1989),
7. PARTITION partDecada90 VALUES IN (1990, 1991, 1992, 1993, 1994, 1995, 199
6, 1997, 1998, 1999),
8. PARTITION partDecada00 VALUES IN (2000, 2001, 2002, 2003, 2004, 2005, 200
6,
9. 2007, 2008, 2009),
10. PARTITION partDecada10 VALUES IN (2010, 2011, 2012, 2013, 2014, 2015, 201
6,
11. 2017, 2018, 2019)
12. );
Por hash: MySQL se encarga de distribuir las tuplas automticamente usando una operacin
de mdulo. Slo hay que pasarle una columna o expresin que resulte en un entero (el hash)
y el nmero de particiones que queramos crear.
view plaincopy to clipboardprint?
1. ALTER TABLE contratos
2. PARTITION BY HASH(YEAR(fechaInicio))
3. PARTITIONS 7;
Por clave: similar a la particin por hash, pero en este caso no necesitamos pasarle un
entero; MySQL utilizar su propia funcin de hash para generarlo. Si no se indica ninguna
columna a partir de la que generar el hash, se utiliza la clave primaria por defecto.
view plaincopy to clipboardprint?
1. ALTER TABLE contratos
2. PARTITION BY KEY()
3. PARTITIONS 7;
Compuesta: podemos combinar los distintos mtodos de particionado y crear particiones de
particiones
Por ltimo, un pequeo ejemplo de cmo afectara el particionado a una consulta sencilla
como obtener el nmero total de tuplas que cumplen una condicin. Estas son las
estadsticas de la consulta sin particionado (ni ndices)
view plaincopy to clipboardprint?
1. EXPLAIN SELECT COUNT(*)
2. FROM contratos
3. WHERE fechaInicio BETWEEN '1950-01-01' AND '1955-12-31'
select_type table type key rows Extra
SIMPLE contratos ALL

239796 Using where
Y este el resultado de aadir las particiones (ntese la palabra clave PARTITIONS para que
nos muestre tambin la informacin relativa a las particiones)
view plaincopy to clipboardprint?
1. EXPLAIN PARTITIONS SELECT COUNT(*)
2. FROM contratos
3. WHERE fechaInicio BETWEEN '1950-01-01' AND '1955-12-31'
select_type table partitions type key rows Extra
SIMPLE contratos partDecada50 ALL

8640 Using where
Como vis, el nmero de tuplas que MySQL tiene que comprobar se ve disminunido en 2
rdenes de magnitud.


Sintaxis para la creacin de las tablas
La estructura de la tabla NonFTP_Access_log sin particionar corresponde a la definida en la
siguiente consulta SQL CREATE TABLE
CREATE TABLE `NonFTP_Access_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`clientip` VARCHAR(15) NOT NULL,
`user` CHAR(7) NOT NULL,
`datetime` datetime NOT NULL,
`method` VARCHAR(10) NOT NULL,
`protocol` VARCHAR(10) NOT NULL,
`domain` VARCHAR(255) NOT NULL,
`uri` VARCHAR(100) NOT NULL,
`return_code` SMALLINT(5) UNSIGNED NOT NULL,
`size` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
INDEX `domain` (`domain`),
INDEX `datetime` (`datetime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
Y con particiones, una para cada mes del 2012 a la siguiente
CREATE TABLE `NonFTP_Access_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`clientip` VARCHAR(15) NOT NULL,
`user` CHAR(7) NOT NULL,
`datetime` datetime NOT NULL,
`method` VARCHAR(10) NOT NULL,
`protocol` VARCHAR(10) NOT NULL,
`domain` VARCHAR(255) NOT NULL,
`uri` VARCHAR(100) NOT NULL,
`return_code` SMALLINT(5) UNSIGNED NOT NULL,
`size` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`, `datetime`),
INDEX `domain` (`domain`),
INDEX `datetime` (`datetime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
partition BY range COLUMNS (datetime)
(
partition p1 VALUES less than ('2012-02-01 00:00:00') engine = myisam,
partition p2 VALUES less than ('2012-03-01 00:00:00') engine = myisam,
partition p3 VALUES less than ('2012-04-01 00:00:00') engine = myisam,
partition p4 VALUES less than ('2012-05-01 00:00:00') engine = myisam,
partition p5 VALUES less than ('2012-06-01 00:00:00') engine = myisam,
partition p6 VALUES less than ('2012-07-01 00:00:00') engine = myisam,
partition p7 VALUES less than ('2012-08-01 00:00:00') engine = myisam,
partition p8 VALUES less than ('2012-09-01 00:00:00') engine = myisam,
partition p9 VALUES less than ('2012-10-01 00:00:00') engine = myisam,
partition p10 VALUES less than ('2012-11-01 00:00:00') engine = myisam,
partition p11 VALUES less than ('2012-12-01 00:00:00') engine = myisam,
partition p12 VALUES less than ('2013-01-01 00:00:00') engine = myisam
);

Potrebbero piacerti anche