Mysql

在生產程式碼中使用索引提示是一種好習慣嗎?

  • March 8, 2022

我遇到了一種情況,我的一個 MySQL (5.6)視圖(類型- MERGE)執行非常糟糕,以便為實體 id獲取記錄(約 3500 行) ,比如****123

該視圖在幾個表之間執行內部連接以獲取這些記錄。

令人驚訝的是,該視圖在我的本地 docker MySQL 容器上返回結果大約需要 200 毫秒,但在 AWS MySQL RDS 實例上需要大約 10 秒。

在查看這兩種環境中的查詢計劃時,我發現連接順序不同,因為用於連接中的一張表的索引不同***(RDS 使用唯一索引,而 docker mysql 使用 PRIMARY)***。

我嘗試了一些方法,例如在所有相關表上使用分析命令重建索引和重建表統計資訊,但都是徒勞的。連接排序規則也與表排序規則相同。數據庫引擎是InnoDB

此外,兩個環境上的數據也是相同的,因為它們是使用相同的轉儲設置的。我還驗證了兩個環境中的索引是相同的。

我可以看到在 RDS 上以最佳方式執行查詢的唯一方法是使用索引提示並按預期執行。

在這種情況下,是否可以在生產程式碼中使用索引提示?

或者我們對如何解決此問題有任何建議?

儘管您的問題是關於 MySQL 的,但 Brent Ozar 有一篇關於 SQL Server的好文章。

通常,出於幾個原因,您希望避免它,數據/統計/索引將來可能會發生變化,然後使用該索引會很糟糕,反而會損害性能。但是,如果沒有其他方法可以解決這個問題,那麼您可以隨時使用它並記錄它以備將來使用。

我已經使用過 RDS 幾次,它可能與在我注意到的機器上使用數據庫不同。您是否使用一種用於開發和一種用於生產?或者兩者有什麼不同的用途?兩者是否具有相同數量的 CPU/RAM?

作為一般規則,您應該只在絕對必要的情況下使用索引提示,並且沒有其他緩解措施(例如稍微不同地編寫查詢或合理減少表上的索引數量)可靠地工作。

你應該避免它的主要原因是因為它需要在你的提示中明確命名一個索引,如果索引隨後被刪除或重命名,你的查詢將完全停止工作(它會出錯,因為它找不到命名的索引)。這為未來從事程式碼庫工作的 DBA 和維護人員創造了隱藏的陷阱。

引用自:https://dba.stackexchange.com/questions/278800