LoginSignup
1
1

More than 5 years have passed since last update.

php で mysql の max_execution_time Optimizer Hint を模倣するサンプル

Posted at

MySQL 5.7 で導入された Optimizer Hint を使うと 特定のクエリの実行時間に制限を設けることができる。

mysql> SELECT /*+ MAX_EXECUTION_TIME(1500) */ SLEEP(10);
+-----------+
| SLEEP(10) |
+-----------+
|         1 |
+-----------+
1 row in set (1.50 sec)

MySQL 5.7 より前のバージョンでアプリ側でどうにかできないの? ってのを試してみたコードがこちら。(エラー制御は省略)

<?php

function connect_db() {
    return new mysqli("127.0.0.1", "user", "pass", "db");
}

$conn->query("SELECT SLEEP(10)", MYSQLI_ASYNC);  // 即時に制御が返る

$links = $errors = $rejects = [$conn];
if (0 < mysqli::poll($links, $errors, $rejects, 1, 500000)) { // 1.5 秒タイムアウトを設定
    // 制限時間内に結果が返る場合
    $result = $conn->reap_async_query();
} else {
    // タイムアウトした場合
    $kill_conn = connect_db();
    $kill_conn->query("KILL QUERY {$conn->thread_id}");
    $kill_conn->close();
}

php 5.3.0 以上で、mysqlnd 版の mysqili 拡張が利用できる環境である必要があります。(php 5.4 以降なら大体の環境で使えるんじゃないかな)

注意点としては、kill するためのコネクションを別に用意する必要があるところ。

上記の例ではタイムアウトするたびにつなぎに行ってしまうけど、kill 専用の持続的接続を用意しておけば、無駄なコネクションも抑制できるかな。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1