

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

`creating sort index` 线程状态表示线程正在处理要求使用内部临时表对数据进行排序的 `SELECT` 语句。

**Topics**
+ [支持的引擎版本](#ams-states.sort-index.context.supported)
+ [上下文](#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

## 上下文
<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>

一般指南是查找带有与 `creating sort index` 状态增加相关的 `ORDER BY` 或 `GROUP BY` 子句的查询。然后看看是添加索引还是增加排序缓冲区大小解决了问题。

**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 上性能详情的性能架构概述](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` 并查找“using filesort”。有关更多信息，请参阅 [检查文件排序使用的解释计划](#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 文档中的 [ORDER 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
```