Particionado Lógico (Parte III)

Gracias a information_schema es posible saber el tamaño que ocupan las tablas de nuestras bases de datos.

Toda la información que nos ofrece information_schema en relación con las tablas es la siguiente:

mysql> desc tables;
+-----------------+--------------+------+-----+---------+-------+
| Field           | Type         | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| TABLE_CATALOG   | varchar(512) | YES  |     | NULL    |       |
| TABLE_SCHEMA    | varchar(64)  | NO   |     |         |       |
| TABLE_NAME      | varchar(64)  | NO   |     |         |       |
| TABLE_TYPE      | varchar(64)  | NO   |     |         |       |
| ENGINE          | varchar(64)  | YES  |     | NULL    |       |
| VERSION         | bigint(21)   | YES  |     | NULL    |       |
| ROW_FORMAT      | varchar(10)  | YES  |     | NULL    |       |
| TABLE_ROWS      | bigint(21)   | YES  |     | NULL    |       |
| AVG_ROW_LENGTH  | bigint(21)   | YES  |     | NULL    |       |
| DATA_LENGTH     | bigint(21)   | YES  |     | NULL    |       |
| MAX_DATA_LENGTH | bigint(21)   | YES  |     | NULL    |       |
| INDEX_LENGTH    | bigint(21)   | YES  |     | NULL    |       |
| DATA_FREE       | bigint(21)   | YES  |     | NULL    |       |
| AUTO_INCREMENT  | bigint(21)   | YES  |     | NULL    |       |
| CREATE_TIME     | datetime     | YES  |     | NULL    |       |
| UPDATE_TIME     | datetime     | YES  |     | NULL    |       |
| CHECK_TIME      | datetime     | YES  |     | NULL    |       |
| TABLE_COLLATION | varchar(64)  | YES  |     | NULL    |       |
| CHECKSUM        | bigint(21)   | YES  |     | NULL    |       |
| CREATE_OPTIONS  | varchar(255) | YES  |     | NULL    |       |
| TABLE_COMMENT   | varchar(80)  | NO   |     |         |       |
+-----------------+--------------+------+-----+---------+-------+
21 rows in set (0.00 sec)

Por ejemplo, si queremos calcular el tamaño de los índices:

mysql> select sum(index_length) from information_schema.tables;
+-------------------+
| sum(index_length) |
+-------------------+
|       11746971648 |
+-------------------+
1 row in set (3.32 sec)

El valor es en bytes, por lo que el tamaño de los índices es de aproximadamente 11 GB. No está nada mal.

Otra forma de sacar un buen resumen con más datos es la siguiente sentencia SQL que encontramos en mysqlperformanceblog.com:

mysql> SELECT
    ->   count(*) TABLES
    ->   ,concat(round(sum(table_rows)/1000000,2),'K') rows
    ->   ,concat(round(sum(data_length)/(1024*1024*1024),2),'G') DATA
    ->   ,concat(round(sum(index_length)/(1024*1024*1024),2),'G') idx
    ->   ,concat(round(sum(data_length+index_length)/(1024*1024*1024),2),'G') total_size
    ->   ,round(sum(index_length)/sum(data_length),2) idxfrac
    -> FROM
    ->   information_schema.TABLES;
+--------+---------+--------+--------+------------+---------+
| TABLES | rows    | DATA   | idx    | total_size | idxfrac |
+--------+---------+--------+--------+------------+---------+
|    929 | 301.52K | 15.73G | 10.94G | 26.67G     |    0.70 |
+--------+---------+--------+--------+------------+---------+
1 row in set (3.75 sec)

Tenemos el número de tablas, filas, tamaño de los datos, índices, tamaño total y la proporción índices/datos.

Si lo que deseamos es saber los datos de una tabla en particular, solo es necesario hacer una busqueda más concreta. De esta forma sabremos, por ejemplo, la tabla candidata para el particionado:

mysql> SELECT
    ->   count(*) TABLES
    ->   ,concat(round(sum(table_rows)/1000000,2),'K') rows
    ->   ,concat(round(sum(data_length)/(1024*1024*1024),2),'G') DATA
    ->   ,concat(round(sum(index_length)/(1024*1024*1024),2),'G') idx
    ->   ,concat(round(sum(data_length+index_length)/(1024*1024*1024),2),'G') total_size
    ->   ,round(sum(index_length)/sum(data_length),2) idxfrac
    -> FROM
    ->   information_schema.TABLES
    -> WHERE table_name LIKE '%log%';
+--------+---------+-------+-------+------------+---------+
| TABLES | rows    | DATA  | idx   | total_size | idxfrac |
+--------+---------+-------+-------+------------+---------+
|      8 | 192.81K | 7.05G | 8.94G | 15.99G     |    1.27 |
+--------+---------+-------+-------+------------+---------+
1 row in set (1.76 sec)

En nuestro caso, prácticamente todos los datos pertenecen a la tabla log. Sus indices son mayores que la memoria RAM del equipo (4 GB) por lo que tendríamos una tabla perfecta para particionar. Cuando INDICES > RAM, particionar se hace más rápido que usar índices :)