使用 TableStudio 加速查詢
TableStudio 能實際測量,而非僅靠猜測。絕不要在可以用以下工具證明其效能時,僅憑直覺就建議新增索引或改寫 SQL。這些工具大多僅限於 PostgreSQL;在其他資料庫引擎上,請使用 explain_query 並根據計畫進行推理。
請先依照 database-workflow 技能中的說明選擇連線。建議在包含真實數據的資料庫上執行分析。近乎空的開發資料庫會產生誤導性的執行計畫。
找出緩慢的來源
- 使用者提到某個查詢或端點: 找出它實際執行的 SQL(來自程式碼或 ORM 的日誌),然後前往「診斷單一陳述式」。
- 「為什麼資料庫這麼慢?」 調用
slow_queries。它會根據pg_stat_statements的累計時間對陳述式進行排序。請保留每一列的query_id;其他工具會用到它。如果該擴充功能尚未安裝,此工具會說明啟用它所涉及的步驟,請傳達此訊息,而非未經詢問就自行安裝。 - 廣泛調校:
workload_index_advisor能找出覆蓋最多資料庫時間的極少數索引,並列出從未被使用過的現有索引。
健康檢查
當使用者詢問資料庫出了什麼問題,或想要進行一般性審查時,請不要進行任何變更,直接回報:
database_health。在總結前,請先閱讀其unavailable清單:如果unavailable中有條目,但 findings 清單為空,這表示檢查被跳過了,而不是一切正常。database_overview以了解大小、最大和最忙碌的資料表,以及連線數。schema_issues(不含table參數)以了解資料庫層級的設計問題。
將最重要的發現放在最前面,用白話文說明:出了什麼問題、忽略它的成本為何、以及修復方法。請包含每個發現的 verify_sql,以便使用者可以驗證該數字,以及任何修復方案的 lock_impact。主動提議將使用者選擇的修復方案,透過下方的「部署它」來執行。
診斷單一陳述式
- 使用 SQL(以及若來自
slow_queries的query_id)調用optimize_query。如果是唯讀陳述式,請傳入analyze: true以執行測量檢查。它會在被復原的交易中執行一次。當沒有值得做的事情時,它會回報already_fast;請直接說明,不要憑空發明一個改進方案。 - 需要更多細節時,請使用
explain_query(僅限唯讀查詢傳入analyze: true)。比較每個節點上的actual_rows與estimated_rows。兩者差距過大表示統計資訊過時(請對該資料表執行ANALYZE),這通常是真正的問題所在,而非缺少索引。 - 帶有
$1, $2佔位符的陳述式需要真實數值才能誠實地規劃。suggest_parameter_values可以從歷史記錄、活躍工作階段和統計資料中找出這些值。
證明修復方案
在推薦任何方案之前,請使用 benchmark_query_variants(查詢實驗室):
- 提供基線 SQL 以及作為
variants的候選方案:一個經過改寫的sql、hypothetical_indexes(使用 hypopg 規劃,絕不實際建立)、hide_indexes,或 plannersettings。或者省略variants,讓find_faster自行提出建議。 - 它會為每組參數回報多次執行的中位數,並檢查每次改寫是否回傳與基線相同的資料列。
- 僅推薦
same_rows為「是」的變體。優先選擇recommendation中的變體。引用測量到的前後差異,而不是憑直覺猜測的百分比。
在刪除一個索引(未使用或重複)之前,請執行 index_what_if 並在 hide 參數中指定該索引。任何因此變得更昂貴,或目前正在使用此索引的陳述式,都會受到影響。
部署它
索引變更和 SQL 改寫應遵循 database-workflow 技能中的常規變更流程:
- 索引變更屬於結構變更。如果儲存庫有遷移工具,請將索引新增到該工具中。否則,請使用
stage_migration來提出建議,並在rationale中包含測量數據。 - 在 PostgreSQL 上,對於任何會接收流量的資料表,請使用
CREATE INDEX CONCURRENTLY,且不要將其包在交易中。 - SQL 改寫屬於程式碼變更:請編輯發出該查詢的程式碼,並在你的總結中提及基準測試結果。