Tengo dos tablas InnoDB idénticas en todos los aspectos, excepto que una está particionada y la otra no:
DROP TABLE IF EXISTS `simple_table`;
CREATE TABLE `simple_table` (
`date` date NOT NULL,
`item_id` bigint(8) NOT NULL DEFAULT '0',
PRIMARY KEY (`date`,`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP TABLE IF EXISTS `partitioned_table`;
CREATE TABLE `partitioned_table` (
`date` date NOT NULL,
`item_id` bigint(8) NOT NULL DEFAULT '0',
PRIMARY KEY (`date`,`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci PARTITION BY RANGE ( TO_DAYS(`date`))
(PARTITION p20180207 VALUES LESS THAN (737098) ENGINE = InnoDB,
PARTITION p20180208 VALUES LESS THAN (737099) ENGINE = InnoDB);
Inserto los mismos datos en ambos:
INSERT INTO `simple_table` (`date`, `item_id`) VALUES ('2018-02-07', 1), ('2018-02-07', 2), ('2018-02-07', 3);
INSERT INTO `simple_table` (`date`, `item_id`) VALUES ('2018-02-08', 1), ('2018-02-08', 2), ('2018-02-08', 3);
INSERT INTO `partitioned_table` (`date`, `item_id`) VALUES ('2018-02-07', 1), ('2018-02-07', 2), ('2018-02-07', 3);
INSERT INTO `partitioned_table` (`date`, `item_id`) VALUES ('2018-02-08', 1), ('2018-02-08', 2), ('2018-02-08', 3);
El resultado es que los datos particionados son el doble de grandes. Aquí está el resultado de SHOW TABLE STATUS
:
*************************** 1. row ***************************
Name: partitioned_table
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 6
Avg_row_length: 5461
Data_length: 32768
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2018-02-19 14:36:29
Update_time: NULL
Check_time: NULL
Collation: utf8_unicode_ci
Checksum: NULL
Create_options: partitioned
Comment:
*************************** 2. row ***************************
Name: simple_table
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 6
Avg_row_length: 2730
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2018-02-19 14:36:29
Update_time: NULL
Check_time: NULL
Collation: utf8_unicode_ci
Checksum: NULL
Create_options:
Comment:
(Mire los Data_length
valores: 16384 vs. 32768)
Lo mismo ocurre con las tablas un poco más complejas y que contienen millones de entradas por fecha: después de aplicarles particiones se vuelven dos veces más grandes. Esto se puede ver en el estado de la tabla, así como en los tamaños reales de los archivos.
No puedo encontrar ninguna información sobre temas como este. ¿Por qué está sucediendo?
ACTUALIZACIÓN: Esto es lo que obtengo si cambio el número de particiones a 10 e inserto 100 entradas para cada fecha (10000 en total para cada una de las dos tablas):
Name: partitioned_table
Data_length: 655360
...
Name: simple_table
Data_length: 344064
(los valores siguen cambiando durante un par de minutos después de las inserciones, pero eventualmente se estabilizan) Y si enumero los archivos, obtengo esto:
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180201.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180202.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180203.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180204.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180205.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180206.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180207.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180208.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180209.ibd
-rw-rw---- 1 mysql mysql 131072 Feb 20 15:50 partitioned_table#P#p20180210.ibd
-rw-rw---- 1 mysql mysql 409600 Feb 20 15:50 simple_table.ibd
-rw-rw---- 1 mysql mysql 128 Feb 20 15:50 partitioned_table.par
-rw-rw---- 1 mysql mysql 8596 Feb 20 15:50 partitioned_table.frm
-rw-rw---- 1 mysql mysql 8596 Feb 20 15:50 simple_table.frm
Respuesta1
Encontré la causa del problema: se debe a la forma en que MySQL asigna espacio en disco para los archivos de tablas en crecimiento.
Ahora me doy cuenta de que mi ejemplo aquí no era tan bueno para el caso que estaba tratando de ilustrar, pero mi problema original era con bases de datos grandes (con millones de filas pequeñas).
encontré estoartículoque habla de laespacio_innodbherramienta mediante la cual descubrí que mis tablas consisten en su mayoría en páginas vacías asignadas, lo que me llevó a este MySQLpágina de documento. Dice:
Las páginas se agrupan en extensiones de tamaño 1 MB para páginas de hasta 16 KB de tamaño.
y
Cuando un segmento crece dentro del espacio de tabla, InnoDB le asigna las primeras 32 páginas una a la vez. Después de eso, InnoDB comienza a asignar extensiones completas al segmento. InnoDB puede agregarhasta 4 extensionesa la vez a un segmento grande para garantizar una buena secuencialidad de los datos.
Esto explica las páginas vacías en mis tablas. Como resultado, los .ibd
archivos pueden ser hasta varias veces más grandes que los datos reales.
La causa raíz no tiene nada que ver con la partición en realidad, pero la partición amplifica el efecto porque los archivos de partición son mucho más pequeños y contienen menos filas que las tablas de un solo archivo (especialmente si hay muchas particiones casi vacías, que todavía tienen tamaños de archivo bastante grandes). )