簡體   English   中英

調試 MySQL 查詢會永久影響執行時間

[英]Debugging a MySQL query permanently affects the execution time

我正在嘗試在一個表上調試一個簡單但運行速度非常慢的 MySQL 查詢,該表與一個非常大的表(13m 行)相連,這個大表有多個索引。

join是很基礎的,只是從小表的ID到大表的foreign_ID的join。

此查詢過去運行速度很快,但此后添加了許多新數據。 之前運行需要 30 毫秒,現在需要 5 分鍾。

在現場,我嘗試通過使用 alter 命令將其設置為 InnoDb 來修復大表。 但這並沒有什么不同。

因此,為了調試查詢,我運行 EXPLAIN 並嘗試刪除連接等,直到查詢再次快速運行。

連接類型以 ALL、eq_ref、ref 和 ref 開始。

然后,當我重新啟用連接並嘗試找到一種使其以高性能方式工作的方法時,我發現實際上現在,原始查詢現在又可以快速工作了。

唯一改變的是查詢執行計划。

連接類型現在是 range、eq_ref、eq_ref 和 ref。

發生了什么? 為什么 MySQL 現在對待同一個查詢的方式與以前不同?

我怎樣才能讓我的實時服務器也這樣做? 我怎樣才能阻止這種情況在未來再次發生?

編輯:MySQL 版本在產品和本地是 5.7

您似乎遇到了經常出現在 MySQL 5.7 及更高版本上的查詢計划程序錯誤。 發生的情況是查詢計划器將決定錯誤的執行計划(索引、連接順序),這會導致對同一數據集的同一查詢有時運行得很快(使用正確的執行計划)或運行緩慢(使用錯誤的執行計划) ,通常會導致全表掃描)。 我在我從事的每個 MySQL 5.7 和 8.0 部署中都看到了這種情況。 在 MySQL 5.6 及更早版本和 MariaDB 上,查詢計划器的這種行為只有通過在表上具有異常大量的索引(10+)才會引起。 因此,如果您在其中一個涉及的表上有很多索引,那么值得嘗試將它們的數量合理化。

除了將每個表上的索引數量保持在盡可能低的水平之外,您還有兩種選擇來解決這個問題:

1) 當您識別遇到此錯誤的查詢時,使用索引提示 (USE/FORCE INDEX (index_name)) 約束它們,並在必要時使用 STRAIGHT_JOIN 來強制 JOIN 排序。

2)切換到 MariaDB 似乎沒有遇到這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM