Eliminar las consultas lentas de nuestra base de datos MySQL

Via Giuseppe Maxia, nos llega un procedimiento almacenado que elimina de la cola de procesos automáticamente cualquier consulta que supere N segundos en ejecutarse o que se tire más de N segundos "idle". Requiere MySQL 5.1.

MySQL:
  1. USE test;
  2.  
  3. DROP PROCEDURE IF EXISTS purge_slow_queries;
  4. DROP PROCEDURE IF EXISTS purge_idle_connections;
  5. DROP event IF EXISTS auto_purge_slow_queries;
  6. DROP event IF EXISTS auto_purge_idle_connections;
  7.  
  8. delimiter //
  9.  
  10. CREATE PROCEDURE purge_idle_connections()
  11. deterministic
  12. BEGIN
  13.     DECLARE done BOOLEAN DEFAULT FALSE;
  14.     DECLARE max_time INT DEFAULT coalesce(@max_kill_time, 200);
  15.     DECLARE pid BIGINT;
  16.     DECLARE c cursor FOR
  17.     SELECT id
  18.     FROM information_schema.processlist
  19.     WHERE command IN ('Sleep')
  20.         AND time> max_time;
  21.     DECLARE continue HANDLER FOR NOT found
  22.         SET done = TRUE;
  23.     open c;
  24.     SET @q_kill = 'KILL ?';
  25.     prepare q_kill FROM @q_kill;
  26.     PURGELOOP: loop
  27.         fetch c INTO pid;
  28.         IF done THEN
  29.             leave PURGELOOP;
  30.         END IF;
  31.         SET @pid = pid;
  32.         execute q_kill USING @pid;
  33.     END loop;
  34.     deallocate prepare q_kill;
  35. END//
  36.  
  37.  
  38. CREATE PROCEDURE purge_slow_queries()
  39. deterministic
  40. BEGIN
  41.     DECLARE done BOOLEAN DEFAULT FALSE;
  42.     DECLARE max_time INT DEFAULT coalesce(@max_kill_time, 200);
  43.     DECLARE pid BIGINT;
  44.     DECLARE c cursor FOR
  45.     SELECT id
  46.     FROM information_schema.processlist
  47.     WHERE state IN ('executing')
  48.         AND time> max_time;
  49.     DECLARE continue HANDLER FOR NOT found
  50.         SET done = TRUE;
  51.     open c;
  52.     SET @q_kill = 'KILL ?';
  53.     prepare q_kill FROM @q_kill;
  54.     PURGELOOP: loop
  55.         fetch c INTO pid;
  56.         IF done THEN
  57.             leave PURGELOOP;
  58.         END IF;
  59.         SET @pid = pid;
  60.         execute q_kill USING @pid;
  61.     END loop;
  62.     deallocate prepare q_kill;
  63. END//
  64.  
  65. delimiter ;
  66.  
  67. CREATE event auto_purge_idle_connections
  68.     ON schedule every 10 SECOND
  69.     DO CALL purge_idle_connections();
  70.  
  71. CREATE event auto_purge_slow_queries
  72.     ON schedule every 10 SECOND
  73.     DO CALL purge_slow_queries();

Términos relacionados: , , , , , , , , ,

Deja tu opinión

Sólo se permiten las etiquetas XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post anteriores/siguientes:

Post (quizás) relacionados:

  • Comparativa MySQL versus PostgreSQL

  • Interesante y detallada comparativa MySQL versus PostgreSQL, dos soluciones de base de datos Open Source y de probada reputación, de la mano de Ciberciti....
  • Base de datos de post de ejemplo

  • Base de datos de post de ejemplo que pueden ayudarte a la hora de hacer previsualizaciones de tus themes de Wordpress....
  • Consultas MySQL útiles

  • Las 10 bases de datos más grandes del servidor [mysql] SELECT count(*) TABLES, table_schema,concat(round(sum(table_rows)/1000000,2),'M') 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 GROUP BY table_schema ORDER BY sum(data_length+index_length) DESC LIMIT 10; [/mysql] Número total de...
  • El tiempo en MySQL, de forma simple

  • Si vienes de otros mundos SQL, estarás acostumbrado a utilizar DATEDIFF y DATEADD para tus consultas entre/a partir de/hasta determinadas fechas. Si bien MySQL dispone...
  • MySQL - Generar SQL para optimizar las tablas más rellenitas

  • ¿ Generar SQL desde MySQL ? Pozi. [mysql] SELECT CONCAT('OPTIMIZE TABLE ', table_name, ';') FROM information_schema.tables WHERE table_schema = aqui_tu_base_de_datos AND table_rows >= 1000; [/mysql] Esto generará una salida de forma automática...