2011-11-24 96 views
5

嗨我在我的服务器上有问题,因为一些MySQL查询需要很长时间才能运行,并占用服务器上的资源。无论如何限制MySQL查询执行时间?

我已经在优化所有查询以提高性能,但由于我们在使用mysql的服务器上使用了相当数量的第三方应用程序,我希望能够设置一个安全措施来防止未来的问题。

我需要的是我可以放置的服务器范围广泛的应用于所有查询,但有可能在每个查询的基础上覆盖它的一些更复杂的报告,这需要一些时间来运行。

我花时间使用Google找到一个解决方案,但到目前为止没有运气,

感谢您的帮助

+1

设置守护进程,这是轮询从MySQL每X秒'SHOW PROCESSLIST'并杀死采取一切查询超过Y秒 – rabudde

+0

是的,我看到了类似的方法来此使用PHP它可以获取所有正在运行的进程和执行次,然后你可以用mysql命令杀死它们。一个聪明的想法,非常令人惊讶的是,没有什么天然的东西可以防止这种情况发生。似乎奇怪的是,mysql会让进程本质上永远运行并占用进程中的所有系统资源。 – x9sim9

+0

.NET中的基类DbCommand具有CommandTimeout属性,它在终止尝试执行命令并生成错误之前设置等待时间。 – Devart

回答

0

没有办法使用MySQL选项来做到这一点。 但是仍然可以使用守护进程来执行此操作,因为@rabudde建议。

在这种情况下,如果你杀掉进程,你将中止事务并且它将被回滚。

+1

请注意,回滚事务也会给服务器带来很大负担!不幸的是,这很难预测,但作为一个经验法则,你应该知道如果一个事务已经运行一段时间并且会触及很多记录,它的回滚时间将会增加。当有多个事务正在进行交互(包括SELECTing)时,这会变得更糟。 –

+0

幸运的是,我可以得到正在执行的查询,所以会放置一些东西来允许非SELECT查询更多的呼吸空间。到目前为止,TBH到目前为止没有与INSERT/UPDATE/REPLACE有关的性能问题,所有的SELECT查询通常都是通过mysql选择不正确的索引,而令人惊讶的是FORCE INDEX(主要)修复了大约90%的这些查询! – x9sim9

3

这是一个纯粹的php解决方案,似乎是迄今为止我设法找到的最简单的解决方案。

$result = mysql_query("SHOW FULL PROCESSLIST"); 
while ($row=mysql_fetch_array($result)) 
{ 
    $process_id = $row["Id"]; 
    if ($row["Time"] > 200) 
    { 
    $sql="KILL {$process_id}"; 
    mysql_query($sql); 
    } 
} 

并且每60秒从CRON脚本运行一次。

人若找到一个更好的解决这个问题,请让我知道

3

您可以使用以下过程来检查运行时间超过300秒的查询。该事件会定期运行该过程并杀死所有长时间运行的查询。

CREATE PROCEDURE DBNAME.kill_long_running_queries() 
BEGIN 

    DECLARE v_qid BIGINT; 
    DECLARE v_finished INT DEFAULT 0; 
    DECLARE c_queries CURSOR FOR SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Query' AND TIME > 300; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1; 

    OPEN c_queries; 

    l_fetch_queries: LOOP 
    FETCH c_queries INTO v_qid; 
    IF v_qid > 0 THEN 
     KILL QUERY v_qid; 
    END IF; 
    IF v_finished THEN 
     LEAVE l_fetch_queries; 
    END IF; 
    END LOOP l_fetch_queries; 
    CLOSE c_queries; 

END 

CREATE EVENT kill_long_running_queries 
ON SCHEDULE EVERY 60 SECOND 
DO CALL DBNAME.kill_long_running_queries(); 
+0

这个很好用,谢谢!从未听说过MySQL事件,需要在_my.cnf_中添加'event_scheduler = 1'行来启用它们。 –