

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

# 正在建立排序索引
<a name="ams-states.sort-index"></a>

`creating sort index` 執行緒狀態指出執行緒正在處理 `SELECT` 陳述式，而此陳述式需要使用內部暫時資料表來排序資料。

**Topics**
+ [支援的引擎版本](#ams-states.sort-index.context.supported)
+ [Context](#ams-states.sort-index.context)
+ [等待變多的可能原因](#ams-states.sort-index.causes)
+ [動作](#ams-states.sort-index.actions)

## 支援的引擎版本
<a name="ams-states.sort-index.context.supported"></a>

下列版本支援這個執行緒狀態資訊：
+ Aurora MySQL 第 2 版，最高至 2.09.2

## Context
<a name="ams-states.sort-index.context"></a>

當具有 `ORDER BY` 或 `GROUP BY` 子句的查詢無法使用現有的索引來執行作業時，`creating sort index` 狀態便會出現。在此情況下，MySQL 需要執行更昂貴的 `filesort` 作業。如果結果集不太大，此作業通常會在記憶體中執行。否則，它涉及在磁碟上建立檔案。

## 等待變多的可能原因
<a name="ams-states.sort-index.causes"></a>

出現 `creating sort index` 本身並不表示有問題。如果效能不佳，並且您經常看到 `creating sort index` 的執行個體，最可能的原因是搭配 `ORDER BY` 或 `GROUP BY` 運算子的慢速查詢。

## 動作
<a name="ams-states.sort-index.actions"></a>

一般指導方針是尋找搭配 `ORDER BY` 或 `GROUP BY` 子句的查詢，這些子句與 `creating sort index` 狀態中的增加相關聯。然後查看新增索引或增加排序緩衝區大小是否可以解決問題。

**Topics**
+ [如果未開啟效能結構描述，請將其開啟](#ams-states.sort-index.actions.enable-pfs)
+ [識別問題查詢](#ams-states.sort-index.actions.identify)
+ [檢查說明計劃以取得檔案排序使用情形](#ams-states.sort-index.actions.plan)
+ [增加排序緩衝區大小](#ams-states.sort-index.actions.increasebuffersize)

### 如果未開啟效能結構描述，請將其開啟
<a name="ams-states.sort-index.actions.enable-pfs"></a>

只在效能結構描述檢測未開啟時，績效詳情才會報告執行緒狀態。當效能結構描述檢測開啟時，績效詳情會改為報告等待事件。效能結構描述檢測會在您調查潛在的效能問題時提供其他洞察和更好的工具。因此，建議您開啟效能結構描述。如需詳細資訊，請參閱[Aurora MySQL 上 Performance Insights 的效能結構描述概觀](USER_PerfInsights.EnableMySQL.md)。

### 識別問題查詢
<a name="ams-states.sort-index.actions.identify"></a>

若要識別目前哪些查詢正在造成 `creating sort index` 狀態中的增加，請執行 `show processlist` 並查看是否有任何查詢具有 `ORDER BY` 或 `GROUP BY`。選擇性地執行 `explain for connection N`，其中 `N` 是搭配 `filesort` 之查詢的程序清單 ID。

若要識別過去哪些查詢造成這些增加，請開啟慢速查詢日誌，並尋找搭配 `ORDER BY` 的查詢。對慢速查詢執行 `EXPLAIN`，並尋找「使用檔案排序」。如需詳細資訊，請參閱[檢查說明計劃以取得檔案排序使用情形](#ams-states.sort-index.actions.plan)。

### 檢查說明計劃以取得檔案排序使用情形
<a name="ams-states.sort-index.actions.plan"></a>

識別哪些陳述式搭配導致 `creating sort index` 狀態的 `ORDER BY` 或 `GROUP BY` 子句。

下列範例顯示如何對查詢執行 `explain`：`Extra` 資料欄顯示此查詢使用 `filesort`。

```
mysql> explain select * from mytable order by c1 limit 10\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: mytable
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2064548
     filtered: 100.00
        Extra: Using filesort
1 row in set, 1 warning (0.01 sec)
```

下列範例顯示在資料欄 `c1` 上建立索引之後對同一查詢執行 `EXPLAIN` 的結果。

```
mysql> alter table mytable add index (c1);
```

```
mysql> explain select * from mytable order by c1 limit 10\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: mytable
   partitions: NULL
         type: index
possible_keys: NULL
          key: c1
      key_len: 1023
          ref: NULL
         rows: 10
     filtered: 100.00
        Extra: Using index
1 row in set, 1 warning (0.01 sec)
```

如需使用索引進行排序最佳化的相關資訊，請參閱 MySQL 文件中的 [Orice By 最佳化](https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html)。

### 增加排序緩衝區大小
<a name="ams-states.sort-index.actions.increasebuffersize"></a>

若要查看特定查詢是否需要已在磁碟上建立檔案的 `filesort` 程序，請在執行查詢之後檢查 `sort_merge_passes` 變數值。下列顯示一個範例。

```
mysql> show session status like 'sort_merge_passes';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Sort_merge_passes | 0     |
+-------------------+-------+
1 row in set (0.01 sec)

--- run query
mysql> select * from mytable order by u limit 10; 
--- run status again:

mysql> show session status like 'sort_merge_passes';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Sort_merge_passes | 0     |
+-------------------+-------+
1 row in set (0.01 sec)
```

如果 `sort_merge_passes` 的值很高，請考慮增加排序緩衝區大小。在工作階段層級套用增加，因為全域增加它可以大幅地增加 RAM MySQL 使用數量。下列範例顯示如何在執行查詢之前變更排序緩衝區大小。

```
mysql> set session sort_buffer_size=10*1024*1024;
Query OK, 0 rows affected (0.00 sec)
-- run query
```