ホームページ > 記事 > PHPフレームワーク > Laravel で最も遅いクエリを見つける方法の簡単な分析
あなたのウェブサイトは遅いですか?ロードに時間がかかりますか?ユーザーは、ほとんど 使い物にならない と不満を抱いていますか?データベースのクエリを確認する必要があります。すべてのデータベース クエリを簡単に分析する優れた方法を紹介します。
もちろん、Web サイトが遅い理由はたくさんありますが、最も一般的な理由の 1 つはデータベース クエリの遅さです。
しかし、laravelでは、(ほとんどの場合)データベースからデータを取得するためにSQLを使用せず、Eloquent ORMとクエリビルダーを使用します。このため、サイトの速度が大幅に遅くなる原因となっているクエリを特定することが困難になる場合があります。
幸いなことに、laravel では、クエリが実行されるたびに呼び出される関数を定義できます。コールバック (ここを参照)。これを行うには、次のコードを任意のサービス プロバイダー (AppServiceProvider など) に追加します。
public function boot() { DB::listen(function ($query) { // TODO: make this useful }); }
ご覧のとおり、変数 $query
を受け取ります。この変数は インスタンスです。 QueryExecuted クラスの。これは、実行されたクエリに関するいくつかの情報にアクセスできることを意味します。
DB::listen(function ($query) { $query->sql; // 执行的 sql 字符串 $query->bindings; // 传递给sql查询的参数(这将替换sql字符串中的 "?") $query->time; // 执行查询所用的时间; });
これは非常に役立つ情報です。$query->time
プロパティを確認することで、遅いクエリを特定できるようになりました。 しかし、これではコード内のどこで クエリが実行されるかがわかりません。
$query
変数からソースに関する情報が得られない場合でも、PHP 組み込み関数 debug_backtrace()
を使用できます。その情報を得るために。
DB::listen(function ($query) { dd(debug_backtrace()); });
これをプロジェクトで実行すると、ブラウザ上に次のようなものが表示されます。
array:63 [▼ 0 => array:7 [▼ "file"=>"/home/cosme/Documents/projects/cosme.dev/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php" "line" => 404 "function" => "App\Providers\{closure}" "class" => "App\Providers\AppServiceProvider" "object" => App\Providers\AppServiceProvider {#140 ▶} "type" => "->" "args" => array:1 [▶] ] 1 => array:7 [▼ "file" => "/home/cosme/Documents/projects/cosme.dev/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php" "line" => 249 "function" => "Illuminate\Events\{closure}" "class" => "Illuminate\Events\Dispatcher" "object" => Illuminate\Events\Dispatcher {#27 ▶} "type" => "->" "args" => array:2 [▶] ] 2 => array:7 [▼ "file" => "/home/cosme/Documents/projects/cosme.dev/vendor/laravel/framework/src/Illuminate/Database/Connection.php" "line" => 887 "function" => "dispatch" "class" => "Illuminate\Events\Dispatcher" "object" => Illuminate\Events\Dispatcher {#27 ▶} "type" => "->" "args" => array:1 [▶] ] ....
これは、各関数呼び出しのリクエストにおけるこれまでの値を含む配列です。各配列の file
キーと line
キーに注目します。
注意深く見ると、この例には 63 個の関数呼び出しがあることがわかります。これは単純なアプリケーションですが、より複雑なアプリケーションではさらに多くなる可能性があります。さらに悪いことに、上部にあるものを見ると、それらはすべてlaravelフレームワークの内部関数です。役立つものが見つかるまで、それぞれを検討する必要がありますか?
ディレクトリ。これは、各 file
をチェックし、次のように vendor/
による呼び出しを除外できることを意味します。 <pre class="brush:php;toolbar:false">DB::listen(function ($query) {
$stackTrace = collect(debug_backtrace())->filter(function ($trace) {
return !str_contains($trace['file'], 'vendor/');
});
dd($stackTrace);
});</pre>
ここでは、
メソッドで、file
現在 $trace
に vendor/
がある場合、それをコレクションから削除します。 上記のコードを実行すると、次のような内容が表示されます:
Illuminate\Support\Collection {#1237 ▼ #items: array:5 [▼ 12 => array:7 [▼ "file" => "/home/cosme/Documents/projects/cosme.dev/app/Models/Post.php" "line" => 61 "function" => "get" "class" => "Illuminate\Database\Eloquent\Builder" "object" => Illuminate\Database\Eloquent\Builder {#310 ▶} "type" => "->" "args" => [] ] 16 => array:6 [▶] 17 => array:6 [▶] 61 => array:7 [▶] 62 => array:4 [▶] ] #escapeWhenCastingToString: false }
項目は大幅に減り、63 個からわずか 5 個になりました。最も重要な点は、コレクション内の最初の項目が、SQL クエリをトリガーする正確な場所であることです。これは、この情報を抽出して最も遅いクエリを見つけることができることを意味します。
public function boot() { DB::listen(function ($query) { $location = collect(debug_backtrace())->filter(function ($trace) { return !str_contains($trace['file'], 'vendor/'); })->first(); // grab the first element of non vendor/ calls $bindings = implode(", ", $query->bindings); // format the bindings as string Log::info(" ------------ Sql: $query->sql Bindings: $bindings Time: $query->time File: ${location['file']} Line: ${location['line']} ------------ "); }); }
これをアプリケーションで使用している場合は、ログ ファイルを確認すると、次のようなクエリ情報が表示されるはずです。
[2022-02-03 02:20:14] local.INFO: ------------ Sql: select "title", "slug", "body" from "posts" where "published" = ? order by "id" desc Bindings: 1 Time: 0.18 File: /home/cosme/Documents/projects/cosme.dev/app/Models/Post.php Line: 61 ----------
これで、どのクエリが最も遅いかがわかり、処理を開始できます。それらを 1 つずつ高速化するか、少なくともキャッシュするようにしてください。
クエリが時間しきい値を超えると、スラック アラートを受け取る場合があります。
あなたとあなたのチームが毎回表示できるダッシュボードを作成できます。クエリが実行されました
#空には限界がありません。
[関連する推奨事項:laravel ビデオチュートリアル
]以上がLaravel で最も遅いクエリを見つける方法の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。