|

Script PHP para sincronizar estructuras de BD MySQL

Interesante script que permite dados dos estructuras del MySQL, obtenidas por ejemplo usando un mysqldump, ver que diferencias hay entre ambos y devuelve las queries necesarias para igualar las dos estrucuras.

Por ejemplo, si tenemos la estructura siguiente:

CREATE TABLE IF NOT EXISTS `archive` (
`id` int(11) NOT NULL auto_increment,
`topFile` varchar(255) NOT NULL default '',
`msgId` int(11) NOT NULL default '0',
`time` timestamp NOT NULL default CURRENT_TIMESTAMP,
`topTpl` varchar(255) NOT NULL default '',
`file` varchar(255) NOT NULL default '',
`template` varchar(255) NOT NULL default '',
`instanceKey` varchar(255) NOT NULL default '',
`orderby` varchar(25) NOT NULL default '',
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10256 ;

Y este otro:

CREATE TABLE IF NOT EXISTS `archive` (
`id` int(11) NOT NULL auto_increment,
`topFile` varchar(255) NOT NULL default '',
`msgId` int(11) NOT NULL default '0',
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`topTpl` varchar(255) NOT NULL default '',
`file` varchar(255) NOT NULL default '',
`template` varchar(255) NOT NULL default '',
`instanceKey` varchar(255) NOT NULL default '',
`encoding` varchar(50) NOT NULL default '',
`orderby` varchar(255) NOT NULL default '',
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10256 ;

Nos devolvería las siguientes sentencias:

ALTER TABLE `archive` ADD `encoding` varchar(50) NOT NULL;
ALTER TABLE `archive` MODIFY `orderby` varchar(255) NOT NULL;
ALTER TABLE `archive` MODIFY `time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP;
ALTER TABLE `archive` DROP PRIMARY KEY;

Un script bastante útil cuando, debido al despiste, tenemos diferencias entre la base de datos de desarrollo y la de producción y no sabemos qué cambios hemos realizado.

Database structure synchronizer

Monolith: consola DBA para MySQL

Monolith es una consola para DBAs de MySQL que programa y automatiza backups para MySQL y monitoriza un número ilimitado de servidores para medir y mejorar su rendimiento. Además genera gráficas para ser utilizadas para informes.
monolith.png
Entre las características que ofrece nos encontramos con la posibilidad de crear enviar informes locales de backups a la consola de monolith, múltiples gráficas, informes HTML, exportación de datos, integración con VisualMining, backups remotos, envío de informes por email.
Monolith – MySQL DBA Console 1.4 Released

jHeidi: cliente MySQL multiplataforma

jHeidi es una versión de Heidi realizado en Java para que se pueda ejecutar en otras plataformas y no solo en Windows.

jheidi.png

Entre las características que ofrece nos encontramos con:

  • Navegador de bases de datos, tablas y campos
  • Crear, actualizar y borrar BD, tablas, campos e índices
  • Ventana para queries
  • Administrador de usuarios
  • Mantenimiento de tablas
  • Administrador de conexiones
  • Exportar datos (CSV, HTML, …)
  • Importar CVS

jHeidi

mytop: clon de top para MySQL

mytop es una aplicación para la línea de comandos que ofrece información de MySQL al estilo del comando top de Unix. La información que devuelve está dividida en dos partes, una primera que muestra la información del servidor y otra que mostraría la información que proporciona el ejecutar PROCESS LIST: id, usuario, query, tiempo, host y base de datos.
mytop.png
Funciona para las versiones de MySQL 3.22.x, 3.23.x, y 4.x (no sé si funciona para 5 porque la ultima versión es de febrero del 2007) y se necesita disponer de Perl 5.005, Getopt::Long, DBI y DBD::mysql, y Term::ReadKey para CPAN.
mytop

Nuevas funcionalidades para MySQL Enterprise

Parece que MySQL va a añadir nuevas funcionalidades en la versión 6.0 que solo van a estar disponibles para la versión Enterprise (de pago). Entre estas novedades habrá funcionalidades relacionadas con el backup online.
Esto supone un separación en dos ramas del desarrollo de MySQL, a parte de pensar en que la versión Enterprise tendrá funcionalidades que no estarán tan testeadas como si estuvieran en la versión Community, la cual está respaldada por una gran cantidad de usuarios.
Just announced: MySQL to launch new features only in MySQL Enterprise

Consejos para optimizar MySQL

Buenos consejos para optimizar MySQL, ordenados por distintas categorías.

Queries

  • Usa EXPLAIN para comprender la ejecución de la query
  • Usa Slow Query Log
  • No uses DISNTINCT cuando usas o puedes usar GROUP BY
  • Crea INSERT o REPLACE en procesos batch y usa LOAD DATA antes que INSERT
  • LIMIT m,n no es tan rápido como parece
  • No uses ORDER BY RAND() si tienes más de dos mil registros
  • Usa SQL_NO_CACHE cuando selecciones datos que se actualizan con frecuencia o son abundantes
  • Evita usar caracteres especiales en los LIKE
  • Evita usar subconsultas correlacionadas en el SELECT y el WHERE
  • No hagas comparaciones calculadas
  • ORDER BY y LIMIT funcionan mejor con
  • No pongas text/blobs en los resultados si no vas a necesitarlos
  • Subqueries en el FROM pueden ser útiles para recuperar BLOBs sin necesidad de ordenarlos. Si haces un join de una tabla consigo misma, puede ser bueno si en la primera obtienes el indice y en segunda obtienes el resto de los datos.
  • ALTER TABLE … ORDER BY puede tomar los datos ordenados cronologicamente y reordenarlos mediante un campo diferente, esto podría hacer que las consultas vayan más rapidas por ese campo, aunque quizás fuera necesario que estuviera en el índice.
  • Es bueno saber cuando dividir una query compleja en la unión de otras más pequeñas
  • Elimina pequeñas cuentas si puedes
  • Haz queries similares para que el cache las use
  • Usa estándares
  • No uses características deprecated
  • Cambia a OR en índices de múltiples campos para que la UNION mejore la velocidad (> mysql 5.0)
  • No uses COUNT (*) en tablas Innodb para cada búsqueda. Para ello deberías usar SQL_CALC_FOUND_ROWS y SELECT FOUND_ROWS()
  • Usa INSERT … ON DUPLICATE KEY update (INSERT IGNORE) para evitar el SELECT

Escalado

  • Usa benchmarking
  • Aisla las cargas de trabajo, no dejes que las tareas administrativas interfieran en el rendimiento (por ejemplo, backups)
  • Testea en vez de hacer debug
  • A la vez que los datos crecen los índices cambian. Haz tu esquema tan modular como tu código.

Rendimiento de red

  • Minimiza el tráfico recuperando solo lo que necesitas.
  • Accede directamente a la paginación con LIMIT no recuperando los anteriores.
  • No uses SELECT *
  • No uses muchas queries rápidas y una algo más compleja puede ser más eficiente.

Mejoras en el sistema operativo

  • Usa particiones en los datos
  • Manten el servidor tan limpio como sea posible
  • Crea un entorno de test

Servidor MySQL

  • innodb_flush_commit=0 puede ayidar en el retraso del slave
  • Optimiza los tipos de datos, se consistente. Usa PROCEDURE ANALYSE() para ayudarte a determinar el tamaño de los datos que necesitas.
  • Si puedes comprime text y blobs
  • Comprime datos estáticos
  • No hagas backup de datos estáticos con frecuencia
  • Activa e incrementa el cache de las queries y el budder si es apropiado
  • Comprueba SHOW STATUS y SHOW VARIABLES
  • Defragmenta tablas, reconstruye índices, haz mantenimiento
  • Aumenta myisam_sort_buffer_size para optimizar inserta largos

Estos son los que me han parecido más interesantes, el resto los podéis encontrar en:

Top 1000 SQL Performance Tips

Gracias David por el aviso

Diferencias entre count(*) count(col)

Algo a tener muy en cuenta es conocer la diferencia entre count(*) y count(col) en consultas a MySQL.
Cuando realizamos un count(*), lo que hacemos es contar filas, si se trata de una tabla MyISAM y no hay un where, es la forma más rápida de obtener el número de registros de una tabla. Si existe un from o un where, es necesario contar el número de resultados.
Diferente es realizar un count(col), ya que cuenta las filas que tienen esa columna distinta de NULL, por lo que siempre habrá que contar todos los resultados.
Siempre me entra la duda entre count(*) y count(1), las “leyendas urbanas” dicen que es preferible el segundo caso ya que en el primero recuperas todos los datos. Yo sinceramente creo que es lo mismo y recuerdo que un consultor de Oracle también me lo dijo en un proyecto.
COUNT(*) vs COUNT(col)

Funciones MySQL para Memcached

Interesante lista de UDFs para trabajar con memcached usando libmemcached. Con estas funciones se puede asignar, obtener, añadir, borrar, incrementar y decrementar objetos en memcached, a parte de indicar que servidor usar y que comportamiento debe tener el servidor en lo referente a las conexiones. Combinando estas funciones con triggers se puede utilizar el cache de memcached.

Entre las funciones encontramos:

  • memc_servers_set()
  • memc_set()
  • memc_get()
  • memc_delete()
  • memc_append()
  • memc_prepend()
  • memc_increment()
  • memc_decrement()
  • memc_replace()
  • memc_servers_set_behavior()
  • memc_list_behaviors()

Memcached Functions for MySQL

Maria: motor de almacenamiento derivado de MyISAM

Maria (curioso el nombre) es un motor de almacenamiento para MySQL derivado de MyISAM y que ofrece recuperación contra fallos (crash safe). Por ahora se descarga independientemente de MySQL 5.1, pero en un futuro formará parte de él.

A parte de ser crash safe también admite logs (incluyendo operaciones de CREATE, DROP, RENAME y TRUNCATE), todos los tipos de filas de MyISAM y el típo específico de Maria.

A parte de los ficheros de la base de datos y de los log, existe un fichero (maria_log_control) que contiene información sobre el estado actual del motor Maria.

Las diferencias con MyISAM son las siguientes:

  • Hay dos tipos de tablas: las que no son transaccionales (no crash safe), siendo guardados sus datos inmediatamente. Las tablas crash safe, que guardan los datos en los logs de Maria, una vez acabada la transacción los datos se guardarán en los ficheros de la base de datos.
  • Maria soporta recuperación automática en el caso de un fallo (crash).
  • Maria admite un único usuario que escriba y varios que lean. MyISAM solo admite sentencias INSERT y SELECT concurrentes.
  • Maria forece el nuevo formato de fila llamado PAGE.
  • Maria soporta operaciones crash-safe sobre varias sentencias mediante la agrupación de las sentencias usando LOCK TABLES y UNLOCK TABLES.

No he visto nada sobre el rendimiento de este motor de base de datos, ni sobre el origen del nombre, espero poder informarme de ello.

MySQL Maria Preview

Procedimientos almacenados de lenguajes externos para MySQL6

External Language Stored Procedures for MySQL es un parche para MySQL 6 que nos permite ejecutar procedimientos almacenados creados en otro lenguaje de programación externo a MySQL.

Los procedimientos almacenados se declaran en SQL usando sintaxis estándar de compilación, mientras que los que se implementan en otros lenguajes de programación se implementan como plugins que se instalan en el servidor en tiempo de ejecución.

Actualmente admite los plugins para Java y Perl, además de dar soporte a peticiones XML-RPC como procedimientos almacenados.

Un ejemplo para Perl sería el siguiente:

sub test1() {
my $dsn= "DBI:mysql:test";
my $dbh= DBI->connect($dsn, undef, undef) or
die "Error al conectar";
$dbh->do("INSERT INTO t1 (txt) VALUES ('hello world')");
return 0;
}

Y se usaría de la siguiente manera:

mysql> CREATE TABLE test.t1 (
seq INT NOT NULL AUTO INCREMENT PRIMARY KEY,
txt VARCHAR(128));
mysql> CREATE PROCEDURE test.test1()
LANGUAGE Perl MODIFIES SQL DATA
EXTERNAL NAME 'MyDBIExample::test1';
mysql> LOCK TABLE test.t1 WRITE;
mysql> CALL test.test1();
mysql> UNLOCK TABLES;
mysql> SELECT * FROM test.t1;

External Language Stored Procedures for MySQL