我試圖調(diào)試的 PHP 應(yīng)用程序在更大的 MySQL 數(shù)據(jù)庫上運行了幾個設(shè)計糟糕的查詢。有幾頁真的很慢,原來是因為幾個查詢。我開始逐個檢查每個查詢,雖然它們很慢,但它們本身并沒有那么慢。經(jīng)過一些進一步的調(diào)試,結(jié)果發(fā)現(xiàn)它們只是在應(yīng)用程序作為準(zhǔn)備好的語句運行時才會變慢。如果我通過 MySQL 客戶端手動運行查詢,大約需要 300 毫秒。如果我通過 MySQL 客戶端運行 create a Prepared statement 并設(shè)置參數(shù)并運行它,大約需要 300 毫秒。如果我從 PHP (mysqli) 運行簡單查詢,大約需要 300 毫秒。如果我像應(yīng)用程序那樣運行它——通過mysqli——作為準(zhǔn)備好的語句,它需要 100 秒。我想也許是mysqli這樣,所以我用 PDO 試了一下,結(jié)果是一樣的。嘗試了不同的 PHP 版本(5.6、7.2、7.3)并得到相同的結(jié)果。所以我給了最后一次機會,寫了一個小的 Go 腳本來測試,我得到了同樣的結(jié)果,事情也得到了改進。現(xiàn)在,如果我從 MySQL 客戶端或 MySQL Workbench 或 PHPStorms 數(shù)據(jù)庫客戶端運行查詢的準(zhǔn)備好的語句版本,它會很快。如果我從代碼運行查詢,它會非???。關(guān)于我應(yīng)該照顧什么,我應(yīng)該在哪里繼續(xù)調(diào)試,任何幫助都將不勝感激。
1 回答

梵蒂岡之花
TA貢獻1900條經(jīng)驗 獲得超5個贊
事實證明,這是由略有不同的執(zhí)行計劃引起的。MySQL 似乎純粹根據(jù)語句創(chuàng)建執(zhí)行計劃,不包括通過mysqli
或使用準(zhǔn)備好的語句時的參數(shù)值PDO
,這是有道理的。然而,當(dāng)它提供完整的查詢時,在我們的例子中它引入了對其中一個表的優(yōu)化,這產(chǎn)生了巨大的差異。
其中一個表(有 550 萬行)在Using join buffer (Block Nested Loop)
使用非準(zhǔn)備語句運行時具有 Extra,而使用準(zhǔn)備好的語句則沒有。這似乎對我們產(chǎn)生了接近 1000 倍的性能差異。
我仍然不確定為什么通過 PHPStorm 或 CLImysql
客戶端這沒有問題,我最好的猜測是,MySQL 中的某些 API 期望在準(zhǔn)備語句時執(zhí)行計劃是完整的,而其他 API 和 CLI 客戶端則不'不。
- 1 回答
- 0 關(guān)注
- 151 瀏覽
添加回答
舉報
0/150
提交
取消