

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 查詢調校指引
<a name="query-tuning-guidance"></a>

在識別工作負載中有問題的查詢後，應調校每個查詢。使用下列有關調校的指引來協助您的工作負載更有效率地執行。

## 最小化掃描的資料列數
<a name="rows-scanned"></a>

儘管看起來很簡單，但在調校查詢時這是一個很好的建議。使用 EXPLAIN 陳述式，並檢閱資料列欄以查看優化工具在每個聯結處掃描的資料列數。嘗試透過建立最佳索引來減少掃描的資料列數，然後重新解釋您的查詢以確認您的工作。如需詳細資訊，請參閱 [MySQL 文件](https://dev.mysql.com/doc/refman/8.0/en/explain-output.html)。

如果您使用分割的資料表，請永遠使用啟用分割區清除的 WHERE 子句進行查詢，以便優化工具無需掃描每個分割區。如果您的 WHERE 子句包含已分割資料欄的常數，則優化工具知道要尋找的分割區，這會使您的查詢更有效率。

此建議的另一個方面是資料庫的設計。查詢中的資料表越少，查詢的速度就越快。如果您可以對資料庫設計反正規化，則可以讓優化工具掃描更少的資料列，從而提高查詢效能。

## 最大限度地減少暫時資料表用量和磁碟上的暫時資料表
<a name="temporary-tables"></a>

如果 Aurora MySQL 相容優化工具無法直接從索引取得所需的查詢結果，則會同時在 RAM 和磁碟上建立暫時資料表。因此，調校的很大一部分是具有適合您的工作負載的正確索引。但是，工作負載中可能存在不能僅依賴索引的查詢，因此某些操作可能在暫時檔案中執行。只要將其保持在最低限度，並確保在磁碟上建立很少的資料表，就可以了。當暫時資料表太大而無法放在記憶體中時，MySQL 會建立磁碟資料表。MySQL 用於檢查內部暫時資料表大小的邏輯是兩個變數值 tmp\_table\_size 和 max-heap-table-size 中較小的一個值。您可以根據工作負載將這些變數調校為最佳值，以便在無法阻止暫時資料表時，僅在極少數情況下將這些資料表推送至磁碟。

## 避免檔案排序
<a name="avoid-file-sorts"></a>

如果您的工作負載具有大量 `ORDER BY` 查詢，解決這些查詢的最佳方法是在資料表上使用正確索引。確保您的多資料欄索引設計良好，以避免在檔案中排序。如果未使用常數掃描前面的資料欄，則無法對資料欄進行排序 (`in`、`>`、`<`、`!=` 和 `BETWEEN` 不允許對右側的下一資料欄進行排序)。在 MySQL 中排序的最佳方法是放置多資料欄索引，該索引會將包含查詢中提供的常數值的資料欄定位至連續結構中排序資料欄的左側。如果實在沒有別的辦法，在沒有檔案排序的情況下您的查詢無法傳回結果，請將排序移至應用程式。

## 避免在高度並行下執行彙總查詢
<a name="avoid-aggregation"></a>

您的工作負載可能具有少量彙總查詢來滿足應用程式內的某些功能。此使用案例需要非常謹慎。InnoDB 引擎適合適當的線上交易處理 (OLTP) 負載，但即使是幾個高度並行的分組查詢也會對 CPU 造成很大的負擔，並且會迅速降低叢集的效能。若要解決需要彙總結果集的使用案例，請將就緒資料預先彙總至讀取的資料表，以便完全避免分組查詢。

## 測試您的查詢的並行性
<a name="concurrency"></a>

調校個別查詢時，記住這些查詢在 Aurora MySQL 相容中的多個 vCPU 上同時執行。單次執行時，您的查詢可能會在測試環境中執行幾毫秒。但這還不是全部。請務必在生產叢集上使用預期的並行層級測試您的查詢並對效能進行基準測試。僅當查詢滿足並行目標時，才將查詢發行至生產。確保在測試指令碼中使用優化工具 `hint sql_no_cache`，以避免從快取中擷取結果。您可以使用 mysqlslap 等工具來執行並行測試並對結果進行基準測試。