MySql: Descubriendo information_schema y PROFILING

 

Recientemente he pasado un entorno mysql de la versión 5.0.32 a una más reciente que ya incluye la base de datos information_schema con tablas de metadatos equivalentes a algunos comandos SHOW ya disponibles anteriormente.

"INFORMATION_SCHEMA es la base de datos de información, que almacena información acerca de todas las otras bases de datos que mantiene el servidor MySQL. Dentro del INFORMATION_SCHEMA hay varias tablas de sólo lectura. En realidad son vistas, no tablas, así que no puede ver ningún fichero asociado con ellas. Cada usuario MySQL tiene derecho a acceder a estas tablas, pero sólo a los registros que se corresponden a los objetos a los que tiene permiso de acceso. "

No me voy a entretener explicando cada uno de ellos pero me gustaria reflexionar un poco sobre el tema. Una de las principales ventajas que veo con la adición de estas tablas es que podemos jugar como con el diccionario de datos de Oracle para construir sentencias ddl o dml dinámicamente. De momento eso ya es un qué. La lista completa de tablas es la siguiente:

+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| KEY_COLUMN_USAGE                      |
| PROFILING                             |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| STATISTICS                            |
| TABLES                                |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
+---------------------------------------+

No voy a decir mucho más... Pero otra cosica interesante a la que me ha llevado la tabla PROFILING es que activando un "profiler" para la sesión actual podemos obtener con más detalle en que se emplea el tiempo que tarda en ejecutarse la consulta. Algo parecido al profiler de Microsoft SqlServer pero más simple. Así funciona:

//Lo activamos para la sesión actual
mysql> SELECT @@profiling;
+---------------------+
| @@profiling         |
+---------------------+
|           0         |
+---------------------+
1 row in set (0.00 sec)

mysql> SET profiling = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE TABLE T1 (id INT);
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW PROFILES;
+----------+----------+------------------------------+
| Query_ID | Duration | Query                        |
+----------+----------+------------------------------+
|        0 | 0.000088 | SET PROFILING = 1            |
|        1 | 0.000136 | DROP TABLE IF EXISTS t1      |
|        2 | 0.011947 | CREATE TABLE t1 (id INT)     |
+----------+----------+------------------------------+
3 rows in set (0.00 sec)

mysql> SHOW PROFILE;
+----------------------+--------------------+
| Status               | Duration           |
+----------------------+--------------------+
| checking permissions | 0.000040           |
| creating table       | 0.000056           |
| After create         | 0.011363           |
| query end            | 0.000375           |
| freeing items        | 0.000089           |
| logging slow query   | 0.000019           |
| cleaning up          | 0.000005           |
+----------------------+--------------------+
7 rows in set (0.00 sec)

mysql> SHOW PROFILE FOR QUERY 1;
+--------------------+-------------+
| Status             | Duration    |
+--------------------+-------------+
| query end          | 0.000107    |
| freeing items      | 0.000008    |
| logging slow query | 0.000015    |
| cleaning up        | 0.000006    |
+--------------------+-------------+
4 rows in set (0.00 sec)

mysql> SHOW PROFILE CPU FOR QUERY 2;
+----------------------+----------+----------+------------+
| Status               | Duration | CPU_user | CPU_system |
+----------------------+----------+----------+------------+
| checking permissions | 0.000040 | 0.000038 |   0.000002 |
| creating table       | 0.000056 | 0.000028 |   0.000028 |
| After create         | 0.011363 | 0.000217 |   0.001571 |
| query end            | 0.000375 | 0.000013 |   0.000028 |
| freeing items        | 0.000089 | 0.000010 |   0.000014 |
| logging slow query   | 0.000019 | 0.000009 |   0.000010 |
| cleaning up          | 0.000005 | 0.000003 |   0.000002 |
+----------------------+----------+----------+------------+
7 rows in set (0.00 sec)

Esto podría usarse con consultas que por ejemplo aparecen en nuestro slow-query log o para detectar cosas raras en sentencias dll que tardan mucho en ejecutarse etc... Pero me parece útil.

Más sobre profiling  en http://dev.mysql.com/doc/refman/5.0/en/show-profiles.html
Más sobre information_schema en http://dev.mysql.com/doc/refman/5.0/es/information-schema.html