Saturday, May 3, 2014

Benchmark MySQL con mysqlslap

Original post: http://anothermysqldba.blogspot.com/2014/05/mysql-benchmark-with-mysqlslap.html

Así que la evaluación comparativa de diferentes consultas de MySQL en contra de su base de datos es una cosa sabia que hacer. Eso debería ser evidente. Mientras que optimizamos consultas lo mejor que podemos utilizar explicar (y EXTENDIDO) llevándolos tiempo para compararlas deberían resultar útiles. 

Este es un simple ejemplo de ejecución de una sentencia mysqlslap. 

Para este ejemplo he cargado la base de datos de MySQL MUNDO. (http://dev.mysql.com/doc/index-other.html ) 

He creado una consulta que se unió a las tres tablas y lo puso en / tmp / tests.sql. El plan es explicar a continuación. 

root@localhost [world]> EXPLAIN EXTENDED SELECT C.Name as City, Y.Name as Country, L.Language,Y.Population FROM City C INNER JOIN Country Y ON C.CountryCode = Y.Code INNER JOIN CountryLanguage L ON C.CountryCode = L.CountryCode WHERE C.Name LIKE 'D%' AND Y.Continent='Europe' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: C
type: range
possible_keys: CountryCode,name_key
key: name_key
key_len: 5
ref: NULL
rows: 127
filtered: 100.00
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: Y
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: world.C.CountryCode
rows: 1
filtered: 100.00
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: L
type: ref
possible_keys: PRIMARY,CountryCode
key: CountryCode
key_len: 3
ref: world.C.CountryCode
rows: 2
filtered: 100.00
Extra: Using index
3 rows in set, 1 warning (0.00 sec)

root@localhost [world]> show warnings \G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select `world`.`C`.`Name` AS `City`,`world`.`Y`.`Name` AS `Country`,`world`.`L`.`Language` AS `Language`,`world`.`Y`.`Population` AS `Population` from `world`.`City` `C` join `world`.`Country` `Y` join `world`.`CountryLanguage` `L` where ((`world`.`Y`.`Code` = `world`.`C`.`CountryCode`) and (`world`.`L`.`CountryCode` = `world`.`C`.`CountryCode`) and (`world`.`Y`.`Continent` = 'Europe') and (`world`.`C`.`Name` like 'D%'))


Ahora la herramienta mysqlslap ha existido desde MySQL 5.1.4 
A continuación se presentan algunos otros enlaces útiles. 
Ahora que tengo mi consulta, me pueden comparar contra la base de datos con el siguiente comando. 

mysqlslap - concurrencia = 150 - iteraciones = 50 - query = / tmp / test.sql - create-schema = mundo 

Una nota: 
La consulta tiene que ser muy limpia, así como la herramienta hace error fácilmente. 
Por ejemplo, la siguiente arrojó el siguiente error: 

SELECT C.Name as City, Y.Name as Country, L.Language,Y.Population
FROM City C
INNER JOIN Country Y ON C.CountryCode = Y.Code
INNER JOIN CountryLanguage L ON C.CountryCode = L.CountryCode
WHERE C.Name LIKE 'D%' AND Y.Continent='Europe' 

Si bien esta consulta funcionaba bien. 

SELECT C.Name as City, Y.Name as Country, L.Language,Y.Population FROM City C INNER JOIN Country Y ON C.CountryCode = Y.Code INNER JOIN CountryLanguage L ON C.CountryCode = L.CountryCode WHERE C.Name LIKE 'D%' AND Y.Continent='Europe' 


La voluntad resultados de referencia de salida de la herramienta para usted 


Benchmark
Average number of seconds to run all queries: 0.104 seconds
Minimum number of seconds to run all queries: 0.096 seconds
Maximum number of seconds to run all queries: 0.141 seconds
Number of clients running queries: 150
Average number of queries per client: 1 


mysqlslap - help le dará muchas opciones para poner a prueba sus consultas con. 

Usted puede hacer todo de forma automática 

# mysqlslap --auto-generate-sql
Benchmark
Average number of seconds to run all queries: 0.243 seconds
Minimum number of seconds to run all queries: 0.243 seconds
Maximum number of seconds to run all queries: 0.243 seconds
Number of clients running queries: 1
Average number of queries per client: 0 


Usted puede probar las inserciones también. Por ejemplo he creado esta tabla: 

CREATE TABLE `foobar_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time_recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB ; 


Entonces prueba con lo siguiente. 

# mysqlslap --concurrency=1150 --iterations=530 --query="use test;insert into foobar_table (id) values (null)" --delimiter=";"
mysqlslap: Could not create thread 


Errores OK no son muy útiles ... Pero esperamos que pueda notar el error. Es difícil tener 1.150 transacciones concurrentes si sólo tiene 530 iteraciones. 


# mysqlslap --concurrency=150 --iterations=30 --query=/tmp/test1.sql --create-schema=test --verbose
Benchmark
Average number of seconds to run all queries: 0.260 seconds
Minimum number of seconds to run all queries: 0.192 seconds
Maximum number of seconds to run all queries: 0.476 seconds
Number of clients running queries: 150
Average number of queries per client: 1


Por ejemplo, la siguiente funcionaba mucho mejor. 

# mysqlslap --concurrency=200 --iterations=1000 --query=" insert into foobar_table (id) values (null)" --verbose --create-schema=test
Benchmark
Average number of seconds to run all queries: 0.282 seconds
Minimum number of seconds to run all queries: 0.217 seconds
Maximum number of seconds to run all queries: 0.726 seconds
Number of clients running queries: 200
Average number of queries per client: 1 


Sólo para demostrar que estamos haciendo inserciones reales .. 

root@localhost [test]> select count(id) from foobar_table;
+-----------+
| count(id) |
+-----------+
| 206091 |
+-----------+
1 row in set (0.13 sec) 

Ahora También debo decir que esto es sólo una base de datos de prueba que uso para las entradas del blog, por lo que no evalúan sus bases de datos de producción en contra de estos resultados. 

Supongo que el punto después de todo esto ... encontrar una consulta problemática, optimizar lo mejor que puede, y punto de referencia. Es mejor conocer sus límites en lugar de sólo una suposición.