【问题标题】:How to set a maximum execution time for a mysql query?如何设置mysql查询的最大执行时间?
【发布时间】:2010-09-29 18:38:43
【问题描述】:

我想为 php 中的 set_time_limit() 等 sql 查询设置最大执行时间。我该怎么办?

【问题讨论】:

标签: mysql sql time limit


【解决方案1】:

我以为它已经存在了一段时间,但根据this

MySQL 5.7.4 引入了为顶级只读 SELECT 语句设置服务器端执行时间限制的功能,以毫秒为单位。

SELECT 
/*+ MAX_EXECUTION_TIME(1000) */ --in milliseconds
* 
FROM table;

请注意,这只适用于只读 SELECT 语句。

更新: 这个变量是在 MySQL 5.7.4 中添加的,并在 MySQL 5.7.8 中重命名为 max_execution_time。 (source)

【讨论】:

  • 它是仅对本次查询有效,还是对共享同一会话(进程 ID)的所有后续查询有效?
  • 它只适用于指定它的查询。如果你去我引用的来源,你可以设置一个全局或会话 max_execution_time。
  • 我认为这个答案有错误。当我尝试将MAX_EXECUTION_TIME=1000 放入SELECT 本身时,会产生ERROR 1064 (42000): You have an error in your SQL syntax 错误。首先是set MAX_EXECUTION_TIME=1000;,然后SELECT 语句起作用。现在它已在会话中设置,可能需要再次使用set MAX_EXECUTION_TIME=0; 清除此外,select syntax documentation 中似乎不支持该语法
  • 您将不得不重写该查询,例如 select /*+ MAX_EXECUTION_TIME(1000) */ * from table
  • 我根据@ManuMohanThekkedath 的建议编辑了答案,在此确认:dev.mysql.com/doc/refman/5.7/en/…
【解决方案2】:

如果您使用 mysql native driver(自 php 5.3 起常见)和 mysqli 扩展,您可以通过异步查询来完成此操作:

<?php

// Heres an example query that will take a long time to execute.
$sql = "
    select *
    from information_schema.tables t1
    join information_schema.tables t2
    join information_schema.tables t3
    join information_schema.tables t4
    join information_schema.tables t5
    join information_schema.tables t6
    join information_schema.tables t7
    join information_schema.tables t8
";

$mysqli = mysqli_connect('localhost', 'root', '');
$mysqli->query($sql, MYSQLI_ASYNC | MYSQLI_USE_RESULT);
$links = $errors = $reject = [];
$links[] = $mysqli;

// wait up to 1.5 seconds
$seconds = 1;
$microseconds = 500000;

$timeStart = microtime(true);

if (mysqli_poll($links, $errors, $reject, $seconds, $microseconds) > 0) {
    echo "query finished executing. now we start fetching the data rows over the network...\n";
    $result = $mysqli->reap_async_query();
    if ($result) {
        while ($row = $result->fetch_row()) {
            // print_r($row);
            if (microtime(true) - $timeStart > 1.5) {
                // we exceeded our time limit in the middle of fetching our result set.
                echo "timed out while fetching results\n";
                var_dump($mysqli->close());
                break;
            }
        }
    }
} else {
    echo "timed out while waiting for query to execute\n";

    // kill the thread to stop the query from continuing to execute on 
    // the server, because we are abandoning it.
    var_dump($mysqli->kill($mysqli->thread_id));
    var_dump($mysqli->close());
}

我给mysqli_query 的标志完成了重要的事情。它告诉客户端驱动程序启用异步模式,同时强制我们使用更详细的代码,但允许我们使用超时(如果需要,还可以发出并发查询!)。另一个标志告诉客户端不要将整个结果集缓冲到内存中。

默认情况下,php 将其 mysql 客户端库配置为在让您的 php 代码开始访问结果中的行之前将查询的整个结果集提取到内存中。这可能需要很长时间才能传输大型结果。我们禁用它,否则我们可能会在等待缓冲完成时超时。

请注意,有两个地方我们需要检查是否超过了时间限制:

  • 实际的查询执行
  • 在获取结果(数据)时

您可以在 PDO 和常规 mysql 扩展中完成类似的操作。它们不支持异步查询,因此您不能在查询执行时间上设置超时。但是,它们确实支持无缓冲的结果集,因此您至少可以在获取数据时实现超时。

对于许多查询,mysql 几乎可以立即开始将结果流式传输给您,因此仅无缓冲查询就可以让您在一定程度上有效地实现某些查询的超时。例如,一个

select * from tbl_with_1billion_rows

可以立即开始流式传输,但是,

select sum(foo) from tbl_with_1billion_rows

需要先处理整个表格,然后才能开始将第一行返回给您。后一种情况是异步查询超时将节省您的地方。它还将使您免于普通的旧死锁和其他问题。

ps - 我没有在连接本身包含任何超时逻辑。

【讨论】:

  • 这太不可思议了......我迫不及待想尝试一下......例如非常适合图形数据查询......
  • 这不会停止 sql server 上正在进行的 mysql 查询。不过,对于不同的问题,这是一个很好的解决方案。
【解决方案3】:

请改写你的查询

select /*+ MAX_EXECUTION_TIME(1000) */ * from table


此语句将在指定时间后终止您的查询

【讨论】:

  • 你能解释一下这是做什么的吗?它是在 1 秒后终止查询,什么都不返回,还是很好并在 1 秒后返回部分结果集?
  • @kurdtpage 它会终止查询并且客户端会出错。请注意,这只是“执行时间”,如果查询已经在 MySQL 内部执行并且当前只是将结果发送到客户端,它将运行任意时间
【解决方案4】:

您可以在其他 S.O. 上找到答案。问题:

MySQL - can I limit the maximum time allowed for a query to run?

在您的数据库服务器上每秒运行的 cron 作业,连接并执行以下操作:

  • 显示进程列表
  • 查找查询时间大于您的最大期望时间的所有连接
  • 为每个进程运行 KILL [进程 ID]

【讨论】:

    【解决方案5】:

    pt_kill 有这样的选项。但它是按需的,而不是持续监控的。它执行@Rafa 的建议。但是,请参阅 --sentinel 以获取有关如何接近 cron 的提示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多