現在の位置: ホーム> 最新記事一覧> getUsage()を使用して、データベースクエリの前後にシステムの圧力の変化を検出してパフォーマンスを改善する方法は?

getUsage()を使用して、データベースクエリの前後にシステムの圧力の変化を検出してパフォーマンスを改善する方法は?

M66 2025-06-11

getUsageとは

getUsage()は、現在のプロセスまたはその子プロセスのリソース使用を取得するPHPネイティブ機能です。ユーザー/カーネル状態のCPU時間、メモリページの障害、コンテキストスイッチング時間など、複数のシステムレベルでデータを含む配列を返します。

 $usage = getrusage();

一般的に使用されるいくつかのフィールドには次のものがあります。

  • ru_utime.tv_secおよびru_utime.tv_usec :ユーザー状態で時間がかかる(秒およびマイクロ秒)

  • ru_stime.tv_secおよびru_stime.tv_usec :システム状態で時間がかかる(秒およびマイクロ秒)

  • RU_MINFLT :ディスクから呼び出す必要のないページエラーの数(ソフトページがありません)

  • ru_majflt :ディスクから呼び出されるページエラーの数(ハード欠落ページ)

  • RU_NVCSWおよびRU_NIVCSW :自発的および非自発的なコンテキストの切り替え時間


データベースクエリの前後にgetUsage()を呼び出します

システムに対するデータベースクエリの影響を監視する最も直接的な方法は、次のとおりです。

  1. クエリの前に1回gettrusage()をlogsします。

  2. クエリを実行します。

  3. クエリ後に再びgetTrusage()を記録します。

  4. 2つのレコードの違いを比較します。

サンプルコードは次のとおりです。

 function getResourceUsageDiff($start, $end) {
    $diff = [];
    foreach ($end as $key => $value) {
        if (isset($start[$key])) {
            $diff[$key] = $value - $start[$key];
        }
    }
    return $diff;
}

$before = getrusage();

// データベースクエリをシミュレートします
$mysqli = new mysqli("localhost", "user", "password", "database");
$result = $mysqli->query("SELECT * FROM users WHERE email LIKE '%@example.com'");

$after = getrusage();

$usageDiff = getResourceUsageDiff($before, $after);

echo "<pre>";
print_r($usageDiff);
echo "
";

このコードは、クエリによって生成されたシステムリソースの変更を出力できます。たとえば、 Ru_stime.tv_usecに大幅な増加が見られる場合、クエリがシステム状態CPUの増加を引き起こし、多数のI/O操作がある可能性があることを意味します。


より直感的なディスプレイ:関数のカプセル化とロギング

より実用的な目的のために、測定プロセスを関数にカプセル化し、クエリステートメントとリソースの変更の自動記録をサポートできます。

 function profileQuery($query, $mysqli) {
    $before = getrusage();

    $result = $mysqli->query($query);

    $after = getrusage();
    $usageDiff = getResourceUsageDiff($before, $after);

    file_put_contents("/var/log/db_profile.log", json_encode([
        'query' => $query,
        'usage' => $usageDiff,
        'time'  => date('c')
    ]) . PHP_EOL, FILE_APPEND);

    return $result;
}

この方法により、通常のロジックを乱すことなく、システムリソースに対するクエリの影響を継続的に収集し、それによりその後の最適化の根拠を提供できます。


実用的なアプリケーションの提案

  1. 異なるインデックス構造の影響の比較
    同じ条件と異なるインデックス構造を持つクエリを使用して、システムリソースの使用量を比較すると、インデックス調整が効果的かどうかを直感的に評価できます。

  2. バッチクエリまたはビッグデータのページングパフォーマンスを監視します
    ページネーションまたはバッチクエリに直面している場合、 Ru_majfltRu_NVCSWが成長するかどうかを観察すると、クエリが多数のメモリページングまたはコンテキストスイッチングをトリガーするかどうかを判断できます。

  3. ストレステストでのリソース使用量の比較
    Apacheベンチマーク、Jmeterなどのツールと協力して、同時テストを実施し、リソースの職業の変更を記録し、高負荷の下でのシステムのパフォーマンスを分析します。


追加:Beautify output(デバッグ用)

デバッグ中にブラウザでgetTrusage()の変更をより明確に確認したい場合は、次のコードを使用して出力をフォーマットできます。

 function formatUsage(array $usage) {
    return sprintf(
        "User CPU: %.4fs, System CPU: %.4fs, Major Faults: %d, Voluntary CS: %d",
        $usage['ru_utime.tv_sec'] + $usage['ru_utime.tv_usec'] / 1e6,
        $usage['ru_stime.tv_sec'] + $usage['ru_stime.tv_usec'] / 1e6,
        $usage['ru_majflt'] ?? 0,
        $usage['ru_nvcsw'] ?? 0
    );
}

echo formatUsage($usageDiff);