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 :自発的および非自発的なコンテキストの切り替え時間
システムに対するデータベースクエリの影響を監視する最も直接的な方法は、次のとおりです。
クエリの前に1回gettrusage()をlogsします。
クエリを実行します。
クエリ後に再びgetTrusage()を記録します。
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;
}
この方法により、通常のロジックを乱すことなく、システムリソースに対するクエリの影響を継続的に収集し、それによりその後の最適化の根拠を提供できます。
異なるインデックス構造の影響の比較
同じ条件と異なるインデックス構造を持つクエリを使用して、システムリソースの使用量を比較すると、インデックス調整が効果的かどうかを直感的に評価できます。
バッチクエリまたはビッグデータのページングパフォーマンスを監視します
ページネーションまたはバッチクエリに直面している場合、 Ru_majfltとRu_NVCSWが成長するかどうかを観察すると、クエリが多数のメモリページングまたはコンテキストスイッチングをトリガーするかどうかを判断できます。
ストレステストでのリソース使用量の比較
Apacheベンチマーク、Jmeterなどのツールと協力して、同時テストを実施し、リソースの職業の変更を記録し、高負荷の下でのシステムのパフォーマンスを分析します。
デバッグ中にブラウザで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);