Laravelで最も遅いクエリを見つける方法の詳細な説明

青灯夜游
リリース: 2022-12-21 21:04:08
転載
1161 人が閲覧しました

Laravelで最も遅いクエリを見つける方法の詳細な説明

#あなたのウェブサイトは遅いですか?ロードに時間がかかりますか?ユーザーは、ほとんど

使い物にならない と不満を抱いていますか?データベースのクエリを確認する必要があります。すべてのデータベース クエリを簡単に分析する優れた方法を紹介します。

もちろん、Web サイトが遅い理由はたくさんありますが、最も一般的な理由の 1 つはデータベース クエリの遅さです。

しかし、laravelでは、(ほとんどの場合)データベースからデータを取得するためにSQLを使用せず、

Eloquent ORMクエリビルダーを使用します。このため、サイトの速度が大幅に遅くなる原因となっているクエリを特定することが困難になる場合があります。 [関連する推奨事項: laravel ビデオチュートリアル]

DB::listen()

幸いなことに、laravel では、次のような A コールバックを定義できます。クエリが実行されるたびに呼び出されます (

ここを参照)。これを行うには、次のコードを任意のサービス プロバイダー (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フレームワークの内部関数です。役立つものが見つかるまで、それぞれを検討する必要がありますか?

クエリの場所の検索

前に述べたように、それらのほとんどは内部フレームワーク呼び出しです。つまり、これらのファイルのほとんどは vendor/## にあります。 # ディレクトリ。これは、各

file

をチェックし、次のように vendor/ による呼び出しを除外できることを意味します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">DB::listen(function ($query) { $stackTrace = collect(debug_backtrace())-&gt;filter(function ($trace) { return !str_contains($trace[&amp;#39;file&amp;#39;], &amp;#39;vendor/&amp;#39;); }); dd($stackTrace); });</pre><div class="contentsignin">ログイン後にコピー</div></div>ここでは、 を使用するために配列を Collection に変換します。 filter メソッドで、

file

現在 $tracevendor/ がある場合、それをコレクションから削除します。 上記のコードを実行すると、次のような内容が表示されます: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Illuminate\Support\Collection {#1237 ▼ #items: array:5 [▼ 12 =&gt; array:7 [▼ &quot;file&quot; =&gt; &quot;/home/cosme/Documents/projects/cosme.dev/app/Models/Post.php&quot; &quot;line&quot; =&gt; 61 &quot;function&quot; =&gt; &quot;get&quot; &quot;class&quot; =&gt; &quot;Illuminate\Database\Eloquent\Builder&quot; &quot;object&quot; =&gt; Illuminate\Database\Eloquent\Builder {#310 ▶} &quot;type&quot; =&gt; &quot;-&gt;&quot; &quot;args&quot; =&gt; [] ] 16 =&gt; array:6 [▶] 17 =&gt; array:6 [▶] 61 =&gt; array:7 [▶] 62 =&gt; array:4 [▶] ] #escapeWhenCastingToString: false }</pre><div class="contentsignin">ログイン後にコピー</div></div>項目は大幅に減り、63 個からわずか 5 個になりました。最も重要な点は、コレクション内の最初の項目が、SQL クエリをトリガーする正確な場所であることです。これは、この情報を抽出して最も遅いクエリを見つけることができることを意味します。

ログへの出力

必要な情報がすべて揃ったので、ログに記録して、検査して最も遅いクエリを見つけられるようにしてみませんか? :
public function boot()
{
    DB::listen(function ($query) {
        $location = collect(debug_backtrace())->filter(function ($trace) {
            return !str_contains($trace[&#39;file&#39;], &#39;vendor/&#39;);
        })->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[&#39;file&#39;]}
            Line: ${location[&#39;line&#39;]}
            ------------
        ");
    });
}
ログイン後にコピー
これをアプリケーションで使用している場合は、ログ ファイルを確認すると、次のようなクエリ情報が表示されるはずです。

[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 つずつ高速化するか、少なくともキャッシュするようにしてください。

拡張デバッグ

これはデバッグに便利ですが、この手法はさまざまな方法で使用できます。

その週の最も遅いクエリを示す週次レポートを作成できます。

クエリが時間しきい値を超えると、スラック アラートを受け取る場合があります。

あなたとあなたのチームが毎回表示できるダッシュボードを作成できます。クエリが実行されました

#空には限界がありません。

元のアドレス: https://dev.to/cosmeoes/how-to-find-the-slowest-query-in-your-application-4igb

翻訳アドレス: https://learnku.com/laravel/t/65164

プログラミング関連の知識については、

プログラミング ビデオ

をご覧ください。 !

以上がLaravelで最も遅いクエリを見つける方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート