這篇“Laravel中如何找到最慢的查詢”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Laravel中如何找到最慢的查詢”文章吧。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計(jì)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了合浦免費(fèi)建站歡迎大家使用!
幸運(yùn)的是,在 laravel 中,我們可以定義一個(gè)在每次執(zhí)行查詢時(shí)調(diào)用的回調(diào)(參見 此處)。為此,請(qǐng)將以下代碼添加到任何服務(wù)提供者(例如 AppServiceProvider):
public function boot() { DB::listen(function ($query) { // TODO: make this useful }); }
如您所見,我們接收了一個(gè)變量 $query
,這個(gè)變量是 QueryExecuted 類的一個(gè)實(shí)例。這意味著我們可以訪問有關(guān)已執(zhí)行查詢的一些信息:
DB::listen(function ($query) { $query->sql; // 執(zhí)行的 sql 字符串 $query->bindings; // 傳遞給sql查詢的參數(shù)(這將替換sql字符串中的 "?") $query->time; // 執(zhí)行查詢所用的時(shí)間; });
這是非常有用的信息,現(xiàn)在我們可以通過查看 $query->time
屬性來識(shí)別慢查詢。 但這并沒有告訴我們?cè)谖覀兊拇a中查詢執(zhí)行的位置。
即使該 $query
變量沒有給我們?nèi)魏侮P(guān)于其來源的信息, 我們?nèi)匀豢梢允褂?PHP 內(nèi)置函數(shù) debug_backtrace()
獲取該信息。
DB::listen(function ($query) { dd(debug_backtrace()); });
如果你在你的項(xiàng)目上運(yùn)行它,你會(huì)在瀏覽器上看到類似這樣的東西:
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 [?] ] ....
這是一個(gè)數(shù)組,其中包含請(qǐng)求中到目前為止的每個(gè)函數(shù)調(diào)用。我將只關(guān)注每個(gè)數(shù)組中的 file
和 line
鍵。
如果你仔細(xì)看,你會(huì)發(fā)現(xiàn)在我的例子中有 63 個(gè)函數(shù)調(diào)用,這是一個(gè)簡(jiǎn)單的應(yīng)用程序,如果在更復(fù)雜的應(yīng)用程序中,可能會(huì)更多。更糟糕的是,如果您查看頂部的那些, 它們都是 laravel 框架的內(nèi)部函數(shù)。我們是否應(yīng)該逐一查看,直到找到可能對(duì)我們有幫助的東西?
正如我之前所說,它們中的大多數(shù)是內(nèi)部框架調(diào)用,這意味著這些文件中的大多數(shù)都在我們的 vendor/
目錄中。這意味著我們可以檢查每個(gè) file
并過濾掉任何具有 vendor/
的調(diào)用,如下所示:
DB::listen(function ($query) { $stackTrace = collect(debug_backtrace())->filter(function ($trace) { return !str_contains($trace['file'], 'vendor/'); }); dd($stackTrace); });
在這里,我將數(shù)組轉(zhuǎn)換為集合以使用該 filter
方法,如果 file
當(dāng)前 $trace
有 vendor/
我們將其從集合中刪除。
如果您運(yùn)行上面的代碼,您將看到如下內(nèi)容:
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 }
這些項(xiàng)目要少得多,我們從 63 個(gè)變成了只有 5 個(gè)。最好的部分是集合中的第一項(xiàng)是我們觸發(fā) 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']} ------------ "); }); }
如果您在應(yīng)用程序中使用它,您可以檢查您的日志文件,您應(yīng)該會(huì)看到如下查詢信息:
[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 ----------
以上就是關(guān)于“Laravel中如何找到最慢的查詢”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。