[PHP][Mysql] ループでレコードを持ってくる時のパフォーマンス考慮

$va_keys = ['key1','key2','key3'];

foreach($va_keys as $v_row){
    $vsql_stmt = $mysql->stmt_init();    // ※ $mysql は mysqli
    $vsql_stmt->prepare('SELECT * FROM blah WHERE id = ?');
    $vsql_stmt->bind_param('s', $v_row);
    $vsql_stmt->execute();
    $vsql_all = $vsql_stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $vsql_stmt->close();

    foreach ($vsql_all as $vsql_row){
        // 取得した内容を処理
    }
}

こんな処理があったとする
キーを全県抽出する処理

コードを見た時、何をしているかわかりやすいが、これだとキーの数だけSELECT文が動作してパフォーマンスが悪い
1000件とかやるとめちゃくちゃ長い

これを考慮する例は IN を使う方法

$va_keys = ['key1','key2','key3'];

$v_prepare = implode(",", array_fill(0, count($va_keys), "?"));

$vsql_stmt = $mysql->stmt_init();    // ※ $mysql は mysqli
$vsql_stmt->prepare('SELECT * FROM blah WHERE id IN (${v_prepare})');
$vsql_stmt->bind_param( str_repeat('s', count($va_data)) , ...$va_keys);
$vsql_stmt->execute();
$vsql_all = $vsql_stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$vsql_stmt->close();

キーの数だけ、IN(?, ?, ?) と展開し、bind_paramも ‘sss’, ‘key1’, ‘key2’, ‘key3’ と指定する例
SELECTの回数は1回だけ

上記例のように3件だけなら差は殆どないが、100~1000になると雲泥の差になる

参考:[PHP] mysqliのbind paramに可変する引数を渡す (agohack.com)


個人用でもこういった考慮の積み重ねでパフォーマンスが変わってくるので、
複雑そう、やめよう、じゃなくて慣れていこう

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Share via
Copy link