
# CREATE INDEX
#### 功能描述
在指定的表上创建索引。**索引（Index）**是一种通过优化数据检索效率的数据结构，其核心作用类似于书籍的目录------通过预先组织关键信息，帮助数据库快速定位所需数据，减少查询时需要扫描的数据量。
索引的核心作用是：
1. **加速查询速度：**
   在处理大量数据的数据库应用中，用户经常遇到查询速度慢的问题，尤其是在没有索引的情况下，数据库查询需要扫描整个表（全表扫描），效率极低。如何提高查询效率，减少数据处理时间？通过建立索引，可以显著提升查询速度。有索引时，可通过索引直接定位到符合条件的数据位置，大幅减少数据扫描量。例如：查询where id=100时，若id列有索引，能直接找到该记录，无需遍历所有行。
   
2. **优化排序和分组操作：**
   索引本身是有序的（如 Btree索引），当查询涉及ORDER BY（排序）或GROUP BY（分组）时，可直接利用索引的有序性，避免额外的排序操作，提升效率。
   
3. **约束数据完整性** ：
   某些索引（如主键索引、唯一索引）可强制列的值唯一（如主键不能重复），辅助维护数据的完整性。
   
 
#### DWS索引支持的类型
DWS支持创建的索引类型包括：
- **B-Tree**：B-Tree索引使用一种类似于B+树的结构来存储数据的键值，通过这种结构能够快速的查找索引。B-Tree适合范围查询、排序、等值查询。
- **GIN**：GIN索引是倒排索引，可以处理包含多个键的值（比如数组），适用场景：多值元素、模糊匹配、全文检索。
- **GiST**：GiST索引适用于几何和地理等多维数据类型和集合数据类型，适用场景：多维数据、空间搜索、复杂范围。
- **PSORT**：PSORT索引是针对列存表进行局部排序索引。
其中，
- **行存表** 支持：**B-Tree** （行存表缺省值）、**GIN** 、**GiST**。
- **列存表** 支持：**PSORT** （列存表缺省值）、**B-Tree** 、**GIN**。
从**分区表**的角度分析，又分为本地索引（LOCAL INDEX），全局索引（GLOBAL INDEX）。
- **本地索引**（LOCAL INDEX）：也叫分区索引，即在分区表的每个区上单独创建索引，本地索引与分区表的分区一一对应，具有与其表相同的分区数和相同的分区范围。当表分区发生变化时，只需维护对应的索引分区。
- **全局索引**（GLOBAL INDEX）：全局索引是跨分区的全局索引，索引结构独立于基表的分区方式，覆盖整个表的所有分区数据。目前DWS不支持全局索引。
 
#### DWS支持的索引方式
表1索引方式 
| 索引方式                  | 描述                                                                                                               |
|:---|:---|
| **唯一索引**              | 可用于约束索引属性值的唯一性，或者属性组合值的唯一性。如果一个表声明了唯一约束或者主键，则DWS自动在组成主键或唯一约束的字段上创建唯一索引（可能是多字段索引），以实现这些约束。目前，DWS只有B-Tree可以创建唯一索引。 |
| **多字段索引**（或复合索引、联合索引） | 一个索引可以定义在表中的多个属性上。目前，DWS中的B-Tree支持多字段索引，且最多可在32个字段上创建索引。                                                         |
| **部分索引**              | 建立在一个表的子集上的索引，这种索引方式只包含满足条件表达式的元组。                                                                               |
| **表达式索引**             | 索引建立在一个函数或者从表中一个或多个属性计算出来的表达式上。表达式索引只有在查询时使用与创建时相同的表达式才会起作用。                                                     |
   
#### 创建索引的原则
索引可以用来提高数据库查询性能，但是不恰当的使用将导致数据库性能下降。建议仅在匹配如下某条原则时创建索引：
- 经常执行查询的字段。
- 在连接条件上创建索引，对于存在多字段连接的查询，建议在这些字段上建立组合索引。例如，select \* from t1 join t2 on t1.a=t2.a and t1.b=t2.b，可以在t1表上的a，b字段上建立组合索引。
- where子句的过滤条件字段上（尤其是范围条件）。
- 在经常出现在order by、group by和distinct后的字段。
- 对于点查询场景，推荐建立B-Tree索引。
在分区表上创建索引与在普通表上创建索引的语法不太相同，使用时请注意，如分区表上不支持并行创建索引、不支持创建部分索引、不支持[NULL FIRST](https://support.huaweicloud.com/devg-dws/dws_04_0946.html)特性。
#### 注意事项
- 索引自身也占用存储空间、消耗计算资源，创建过多的索引将对数据库性能造成负面影响（尤其影响数据导入的性能，建议在数据导入后再建索引）。因此，仅在必要时创建索引。
- 索引定义里的所有函数和操作符都必须是immutable类型的，即结果只依赖于其输入参数，而不受任何外部的影响（如另外一个表的内容或者当前时间），该限制可以确保该索引的行为是定义良好的。在一个索引上或WHERE语句中使用用户定义函数，请将其标记为immutable类型函数。
- 在分区表上创建索引时，索引项中必须包含分布列和所有分区键。
- DWS在分区表上创建索引时只支持本地索引（LOCAL INDEX），不支持全局索引（GLOBAL INDEX）。
- 列存表和HDFS表支持B-Tree索引，不支持创建表达式索引、部分索引。
- 列存表支持通过B-Tree索引建立唯一索引。
- 列存表和HDFS表支持的PSORT索引不支持创建表达式索引、部分索引和唯一索引。
- 列存表支持的GIN索引支持创建表达式索引，但表达式不能包含空分词、空列和多列，不支持创建部分索引和唯一索引。
- 列存索引不支持OR查询过滤条件及inlist场景。
- roundrobin表不支持创建主键/唯一索引。
- 对表执行CREATE INDEX或REINDEX操作时会触发索引重建（索引重建过程中会先把数据转储到一个新的数据文件中，重建完成之后会删除原始文件），当表比较大时，重建会消耗较多的磁盘空间。当磁盘空间不足时，要谨慎对待大表CREATE INDEX或REINDEX操作，防止触发集群只读。
![](https://support.huaweicloud.com/sqlreference-dws/public_sys-resources/warning_3.0-zh-cn.png)
- 针对有大批量数据增删改的表，索引个数建议控制在3个以内，最多不超过5个。
- 避免在业务高峰期对大表执行CREATE INDEX和REINDEX操作。
- 更多开发设计规范参见[总体开发设计规范](https://support.huaweicloud.com/devg-dws/dws_04_0075.html)。
 
#### 语法格式
- 在表上创建索引。
  ```
  CREATE [ UNIQUE ] INDEX [ [IF NOT EXISTS] [ schema_name. ] index_name ] ON table_name [ USING method ]
      ({ { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] }[, ...] )
      [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ]
      [ COMMENT 'text' ]
      [ WITH ( {storage_parameter = value} [, ... ] ) ]
      
      [ WHERE predicate ];
  ```
  
- 在分区表上创建索引。
  ```
  CREATE [ UNIQUE ] INDEX [ [IF NOT EXISTS] [ schema_name. ] index_name ] ON table_name [ USING method ]
      ( {{ column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS LAST ] }[, ...] )
      [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ]
      [ COMMENT 'text' ]
      LOCAL [ ( { PARTITION index_partition_name  } [, ...] ) ]
      [ WITH ( { storage_parameter = value } [, ...] ) ]
      ;
  ```
  
 
#### 参数说明
表2CREATE INDEX参数说明 
| 参数                                                                                                                                         | 描述                                                                                                                                                                                                                                                                                                                                                                                        | 取值范围                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
|:---|:---|:---|
| UNIQUE                                                                                                                                     | 创建唯一性索引，每次添加数据时检测表中是否有重复值。如果插入或更新的值会引起重复的记录时，系统会报错。 目前只有行存表B-Tree索引和列存表的B-Tree索引支持唯一索引。                                                                                                                                                                                                                                 | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| IF NOT EXISTS                                                                                                                              | 指定IF NOT EXISTS时，若不存在同名索引，则可以成功创建索引。若已存在同名索引，创建时不会报错，仅会提示该索引已存在，且不执行任何操作。当使用IF NOT EXISTS时，需要指定索引名。该参数仅9.1.0及以上集群版本支持。                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| schema_name                                                                                                                                | 要创建的索引所在的模式名。指定的模式名需与表所在的模式相同。                                                                                                                                                                                                                                                                                                                                                            | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| index_name                                                                                                                                 | 要创建的索引名，索引的模式与表相同。                                                                                                                                                                                                                                                                                                                                                                        | 字符串，需符合[标识符命名规范](https://support.huaweicloud.com/sqlreference-dws/dws_06_0007.html#ZH-CN_TOPIC_0000001811634529__section1475018612353)。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| table_name                                                                                                                                 | 需要为其创建索引的表的名字，可以用模式修饰。                                                                                                                                                                                                                                                                                                                                                                    | 已存在的表名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| USING method                                                                                                                               | 指定创建索引的方法。 - 行存表支持的索引类型：btree（行存表缺省值）、gin、gist。  - 列存表支持的索引类型：psort（列存表缺省值）、btree、gin。   | 创建索引的方法支持： - **btree**：B-Tree索引使用一种类似于B+树的结构来存储数据的键值，通过这种结构能够快速的查找索引。B-Tree适合支持比较查询以及查询范围。  - **gin**：GIN索引是倒排索引，可以处理包含多个键的值（比如数组）。  - **gist**：GiST索引适用于几何和地理等多维数据类型和集合数据类型。  - **psort**：PSORT索引。针对列存表进行局部排序索引。                                                                                                       |
| column_name                                                                                                                                | 表中需要创建索引的列的名字（字段名）。                                                                                                                                                                                                                                                                                                                                                                       | 如果索引方式支持多字段索引，可以声明多个字段。最多可以声明32个字段。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| expression                                                                                                                                 | 创建一个基于该表的一个或多个字段的表达式索引，通常必须写在圆括号中。                                                                                                                                                                                                                                                                                | 如果表达式有函数调用的形式，圆括号可以省略。 表达式索引可用于获取对基本数据的某种变形的快速访问。比如，一个在upper(col)上的函数索引将允许WHERE upper(col) = 'JIM'子句使用索引。 在创建表达式索引时，如果表达式中包含IS NULL子句，则这种索引是无效的。此时，建议用户尝试创建一个部分索引。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| COLLATE collation                                                                                                                          | COLLATE子句指定列的排序规则（该列必须是可排列的数据类型）。如果没有指定，则使用默认的排序规则。                                                                                                                                                                                                                                                                                                                                       | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| opclass                                                                                                                                    | 操作符类的名字。                                                                                                                                                                                                                                                                                                                                                                                  | 对于索引的每一列可以指定一个操作符类，操作符类标识了索引那一列的使用的操作符。例如一个B-Tree索引在一个四字节整数上可以使用int4_ops；这个操作符类包括四字节整数的比较函数。 实际上对于列上的数据类型默认的操作符类是足够用的。操作符类主要用于一些有多种排序的数据。例如，用户想按照绝对值或者实数部分排序一个复数。能通过定义两个操作符类然后在建立索引时选择合适的类。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ASC                                                                                                                                        | 指定按升序排序 （默认）。本选项仅行存支持。                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| DESC                                                                                                                                       | 指定按降序排序。本选项仅行存支持。                                                                                                                                                                                                                                                                                                                                                                         | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| NULLS FIRST                                                                                                                                | 指定空值在排序中排在非空值之前，当指定DESC排序时，本选项为默认的。                                                                                                                                                                                                                                                                                                                                                       | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| NULLS LAST                                                                                                                                 | 指定空值在排序中排在非空值之后，未指定DESC排序时，本选项为默认的。                                                                                                                                                                                                                                                                                                                                                       | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| NULLS DISTINCT NULLS NOT DISTINCT NULLS IGNORE | 指定Unique唯一索引中索引列NULL值的处理方式。                                                                                                                                                                                                                                                                                                                                                               | 默认取值：该参数默认取值为空，即NULL值可重复插入。 在对插入的新数据和表中原始数据进行列的等值比较时，对于NULL值有以下三种处理方式： - NULLS DISTINCT：将每个NULL值视为不同的值，即允许NULL值重复插入。  - NULLS NOT DISTINCT：将所有NULL值视为相同的值，即索引中只保留一个NULL值条目，不允许NULL值重复插入，只有非NULL值且与原索引列中已有数据不相等的数据可插入。  - NULLS IGNORE：在等值比较时跳过NULL值。若索引列全为NULL，则NULL值可重复插入；部分索引列为NULL，只有非NULL值且与原索引列中已有数据不相等的数据可插入。   三种处理方式具体的行为参见[表4]所示。 |
| COMMENT 'text'                                                                                                                             | 指定索引的注释信息。                                                                                                                                                                                                                                                                                                                                                                                | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| WITH ( {storage_parameter = value} \[, ... \] )                                                                                            | 指定索引方法的存储参数。包括：**FILLFACTOR** 、**INVISIBLE** 、**FASTUPDATE** 、**GIN_PENDING_LIST_LIMIT**。                                                                                                                                                                                                                                                                                                 | 取值范围和详细用法参见[表3]。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| WHERE predicate                                                                                                                            | 创建一个部分索引。 部分索引是一个只包含表的一部分记录的索引，通常是该表中比其他部分数据更有用的部分。例如，有一个表，表里包含已记账和未记账的订单，未记账的订单只占表的一小部分而且这部分是最常用的部分，此时就可以通过只在未记账部分创建一个索引来改善性能。另外一个可能的用途是使用带有UNIQUE的WHERE强制一个表的某个子集的唯一性。                                                                                                                                                                    | predicate表达式只能引用表的字段，它可以使用所有字段，而不仅是被索引的字段。目前，子查询和聚集表达式不能出现在WHERE子句里。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| LOCAL                                                                                                                                      | 本地索引（分区索引），即在分区表的每个区上单独创建索引，本地索引与分区表的分区一一对应，具有与其表相同的分区数和相同的分区范围。当表分区发生变化时，只需维护对应的索引分区。                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| PARTITION index_partition_name                                                                                                             | 索引分区的名称。                                                                                                                                                                                                                                                                                                                                                                                  | 字符串，需符合标识符的命名规范。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   
 表3WITH ( {storage_parameter = value} \[, ... \] )指定索引方法的存储参数 
| 存储参数                                                                 | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 示例                                                                                                                                                                                                                                                                                                                                                    |
|:---|:---|:---|
| **FILLFACTOR**  | **GIN和PSORT索引不支持该参数**，表示一个索引的填充因子（fillfactor），取值范围是一个介于10和100之间的百分比值，用于指定索引页初始填充的百分比，剩余的空间可以用于后续的插入和更新操作，从而减少页面分裂和提高性能。 该参数的作用是控制索引页的填充程度，从而影响数据库的性能和存储空间的利用效率，通过调整FILLFACTOR的值，可以减少后续更新或插入操作导致的页分裂，优化索引的存储和性能。  **FILLFACTOR对索引性能的影响**： - **性能**：当索引页填满后，新的数据插入会导致页面分裂，这会消耗更多的I/O资源和时间。较低的 fillfactor可以减少页面分裂，提高插入和更新性能，但会增加存储空间的使用。较高的 fillfactor可以提高存储空间的利用率，但可能会导致更多的页面分裂，降低插入和更新性能。  - **存储空间**：较低的fillfactor会增加每个数据页面的空闲空间，导致更多的磁盘空间使用。较高的fillfactor会更紧凑地存储数据，减少磁盘空间使用。    **如何选择合适的FILLFACTOR值**： - 对于更新频繁的表，选择较小fillfactor值。例如60\~80，预留空间，减少页分裂。  - 对于更新较少的表，选择较大fillfactor值。例如90\~100，以提高存储空间利用率。   | 在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定B-Tree索引，并指定该索引的填充因子**FILLFACTOR**为70%。 这意味着每个数据页面在初次填充时只会填满70%。剩余的30%空间留给将来的插入和更新操作。 ``` CREATE INDEX ds_ship_mode_t1_index6 ON tpcds.ship_mode_t1 USING btree(SM_SHIP_MODE_SK) WITH (FILLFACTOR = 70); ``` |
| **INVISIBLE**                                                        | 控制优化器是否生成索引扫描相关计划。 **适用场景**：维护期间临时禁用索引，或测试索引对性能的影响。 **取值范围**： - ON表示不生成索引扫描相关计划。  - OFF表示生成索引扫描相关计划。   **默认值**：OFF                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定B-Tree索引，并设置**优化器不生成该索引扫描相关计划** ``` CREATE INDEX ds_ship_mode_t1_index7 ON tpcds.ship_mode_t1 USING btree(SM_SHIP_MODE_SK) WITH (INVISIBLE = ON); ```                                                                                                        |
| **FASTUPDATE**                                                       | **仅GIN索引支持该参数**，GIN索引是否使用快速更新，当启用后，数据变更会暂存到待处理列表（Pending List）。 **取值范围**： - ON，表示使用快速更新。  - OFF，表示关闭快速更新。   **默认值**：ON                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定GIN索引，并打开快速更新参数**FASTUPDATE**，设置该索引Pending List容量的最大值为8MB。 ``` CREATE INDEX ds_ship_mode_t1_index8 ON tpcds.ship_mode_t1 USING gin(SM_SHIP_MODE_SK) WITH (FASTUPDATE = ON, GIN_PENDING_LIST_LIMIT = 8192); ```                                               |
| **GIN_PENDING_LIST_LIMIT**                                           | **仅GIN索引支持该参数**，当GIN索引启用fastupdate时，设置该索引Pending List容量的最大值。 **Pending List**是GIN索引特有的数据结构，用于临时存储索引更新操作。当GIN索引启用FASTUPDATE参数时，新的索引项不会直接写入主索引结构，而是先存入Pending List，待满足特定条件时再批量合并到主索引中。 **取值范围**：64\~INT_MAX，单位KB。 **默认值** ：由GUC参数[gin_pending_list_limit](https://support.huaweicloud.com/devg-dws/dws_04_0925.html)的值决定（默认为4MB）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | 在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定GIN索引，并打开快速更新参数**FASTUPDATE**，设置该索引Pending List容量的最大值为8MB。 ``` CREATE INDEX ds_ship_mode_t1_index8 ON tpcds.ship_mode_t1 USING gin(SM_SHIP_MODE_SK) WITH (FASTUPDATE = ON, GIN_PENDING_LIST_LIMIT = 8192); ```                                               |
   
 表4唯一索引中索引列NULL值的处理方式 
| 字段控制               | 索引列全为NULL | 部分索引列为NULL                     |
|:---|:---|:---|
| NULLS DISTINCT     | 可重复插入。    | 可重复插入。                         |
| NULLS NOT DISTINCT | 不可重复插入。   | 非NULL值相等，不可插入；非NULL值不相等，则插入成功。 |
| NULLS IGNORE       | 可重复插入。    | 非NULL值相等，不可插入；非NULL值不相等，则插入成功。 |
   
#### 示例
- 创建示例表tpcds.ship_mode_t1。
  ```
  DROP SCHEMA IF EXISTS tpcds CASCADE;
  CREATE SCHEMA tpcds;
  DROP TABLE IF EXISTS tpcds.ship_mode_t1;
  CREATE TABLE tpcds.ship_mode_t1
  (
      SM_SHIP_MODE_SK           INTEGER               NOT NULL,
      SM_SHIP_MODE_ID           CHAR(16)              NOT NULL,
      SM_TYPE                   CHAR(30)                      ,
      SM_CODE                   CHAR(10)                      ,
      SM_CARRIER                CHAR(20)                      ,
      SM_CONTRACT               CHAR(20)
  ) 
  DISTRIBUTE BY HASH(SM_SHIP_MODE_SK);
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建唯一索引。
  ```
  CREATE UNIQUE INDEX ds_ship_mode_t1_index1 ON tpcds.ship_mode_t1(SM_SHIP_MODE_SK);
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建UNIQUE唯一索引，并指定NULL值的处理方式。
  ```
  CREATE UNIQUE INDEX ds_ship_mode_t1_index5 ON tpcds.ship_mode_t1(SM_SHIP_MODE_SK) NULLS NOT DISTINCT;
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建索引时添加索引的注释。
  ```
  CREATE INDEX ds_ship_mode_t1_index_comment ON tpcds.ship_mode_t1(SM_SHIP_MODE_SK) COMMENT 'index';
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定B-Tree索引。
  ```
  CREATE INDEX ds_ship_mode_t1_index4 ON tpcds.ship_mode_t1 USING btree(SM_SHIP_MODE_SK);
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定B-Tree索引，并指定该索引的填充因子**FILLFACTOR**为70%。
  ```
  CREATE INDEX ds_ship_mode_t1_index6 ON tpcds.ship_mode_t1 USING btree(SM_SHIP_MODE_SK) WITH (FILLFACTOR = 70);
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定B-Tree索引，并设置**优化器不生成该索引扫描相关计划**(默认为OFF，表示生成，ON表示不生成)。
  ```
  CREATE INDEX ds_ship_mode_t1_index7 ON tpcds.ship_mode_t1 USING btree(SM_SHIP_MODE_SK) WITH (INVISIBLE = ON);
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建指定GIN索引，并打开快速更新参数**FASTUPDATE**，设置该索引Pending List容量的最大值为8MB。
  ```
  CREATE INDEX ds_ship_mode_t1_index8 ON tpcds.ship_mode_t1 USING gin(SM_SHIP_MODE_SK) WITH (FASTUPDATE = ON, GIN_PENDING_LIST_LIMIT = 8192);
  ```
  在表tpcds.ship_mode_t1上SM_CODE字段上创建表达式索引。
  ```
  CREATE INDEX ds_ship_mode_t1_index2 ON tpcds.ship_mode_t1(SUBSTR(SM_CODE,1 ,4));
  ```
  在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建SM_SHIP_MODE_SK大于10的部分索引。
  ```
  CREATE UNIQUE INDEX ds_ship_mode_t1_index3 ON tpcds.ship_mode_t1(SM_SHIP_MODE_SK) WHERE SM_SHIP_MODE_SK>10;
  ```
  

- 创建示例表tpcds.customer_address_p1。
  ```
  DROP TABLE IF EXISTS tpcds.customer_address_p1;
  CREATE TABLE tpcds.customer_address_p1
  (
      CA_ADDRESS_SK             INTEGER               NOT NULL,
      CA_ADDRESS_ID             CHAR(16)              NOT NULL,
      CA_STREET_NUMBER          CHAR(10)                      ,
      CA_STREET_NAME            VARCHAR(60)                   ,
      CA_STREET_TYPE            CHAR(15)                      ,
      CA_SUITE_NUMBER           CHAR(10)                      ,
      CA_CITY                   VARCHAR(60)                   ,
      CA_COUNTY                 VARCHAR(30)                   ,
      CA_STATE                  CHAR(2)                       ,
      CA_ZIP                    CHAR(10)                      ,
      CA_COUNTRY                VARCHAR(20)                   ,
      CA_GMT_OFFSET             DECIMAL(5,2)                  ,
      CA_LOCATION_TYPE          CHAR(20)
  )
  DISTRIBUTE BY HASH(CA_ADDRESS_SK)
  PARTITION BY RANGE(CA_ADDRESS_SK)
  ( 
     PARTITION p1 VALUES LESS THAN (3000),
     PARTITION p2 VALUES LESS THAN (5000) ,
     PARTITION p3 VALUES LESS THAN (MAXVALUE) 
  )
  ENABLE ROW MOVEMENT;
  ```
  创建分区表索引ds_customer_address_p1_index1，不指定索引分区的名字。
  ```
  CREATE INDEX ds_customer_address_p1_index1 ON tpcds.customer_address_p1(CA_ADDRESS_SK) LOCAL;
  ```
  创建分区表索引ds_customer_address_p1_index2，并指定索引分区的名字。
  ```
  CREATE INDEX ds_customer_address_p1_index2 ON tpcds.customer_address_p1(CA_ADDRESS_SK) LOCAL
  (
      PARTITION CA_ADDRESS_SK_index1,
      PARTITION CA_ADDRESS_SK_index2,
      PARTITION CA_ADDRESS_SK_index3 
  ) 
  ;
  ```
  创建分区表索引ds_customer_address_p1_index_comment，并添加索引注释。
  ```
  CREATE INDEX ds_customer_address_p1_index_comment ON tpcds.customer_address_p1(CA_ADDRESS_SK) COMMENT 'index' LOCAL
  (
      PARTITION CA_ADDRESS_SK_index1,
      PARTITION CA_ADDRESS_SK_index2,
      PARTITION CA_ADDRESS_SK_index3 
  ) 
  ;
  ```
  
 
 #### 关于NULLS DISTINCT、NULLS NOT DISTINCT、NULLS IGNORE使用上的场景差异
以下举例说明这3个参数的使用差异，便于理解。
示例：假设有一张表users，包含id和email（可能为 NULL，表示未提供邮箱）。
**场景 1：默认 NULLS DISTINCT（NULL可重复插入）**
```
-- 创建表
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id INT,
  email TEXT
)
DISTRIBUTE BY HASH(email);
-- 创建唯一索引（默认 NULLS DISTINCT）
CREATE UNIQUE INDEX idx_email_unique ON users (email);
-- 插入数据
INSERT INTO users (id, email) VALUES (1, NULL); -- 成功
INSERT INTO users (id, email) VALUES (2, NULL); -- 成功（NULL 被视为不同）
INSERT INTO users (id, email) VALUES (3, 'a@example.com'); -- 成功
INSERT INTO users (id, email) VALUES (4, 'a@example.com'); -- 失败（非 NULL 重复）
```
![](https://support.huaweicloud.com/sqlreference-dws/figure/zh-cn_image_0000002274564324.png "点击放大")
**场景 2：NULLS NOT DISTINCT（NULL不可重复插入）**
```
-- 重新创建唯一索引，指定NULLS NOT DISTINCT
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id INT,
  email TEXT
)
DISTRIBUTE BY HASH(email);
CREATE UNIQUE INDEX idx_email_unique ON users (email) NULLS NOT DISTINCT;
-- 插入数据
INSERT INTO users (id, email) VALUES (5, NULL); -- 成功（第一个 NULL）
INSERT INTO users (id, email) VALUES (6, NULL); -- 失败（第二个 NULL，违反唯一约束）
INSERT INTO users (id, email) VALUES (7, 'b@example.com'); -- 成功
INSERT INTO users (id, email) VALUES (8, 'b@example.com'); -- 失败（非 NULL 重复）
```
**场景 3：NULLS IGNORE（忽略NULL值）**
```
-- 创建索引，忽略NULL值
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id INT,
  email TEXT
)
DISTRIBUTE BY HASH(email);
CREATE UNIQUE INDEX idx_email_ignore ON users (email) NULLS IGNORE;
-- 插入数据
INSERT INTO users (id, email) VALUES (9, NULL); -- 成功（第一个 NULL）
INSERT INTO users (id, email) VALUES (10, NULL); -- 成功（NULL值被忽略）
INSERT INTO users (id, email) VALUES (11, 'c@example.com'); -- 成功
INSERT INTO users (id, email) VALUES (12, 'c@example.com'); -- 失败（非 NULL 重复）
```
#### 相关链接
- 修改和删除索引语法参见[ALTER INDEX](https://support.huaweicloud.com/sqlreference-dws/dws_06_0128.html)和[DROP INDEX](https://support.huaweicloud.com/sqlreference-dws/dws_06_0195.html)。
- 更多索引案例请参见[创建和管理索引](https://support.huaweicloud.com/devg-dws/dws_04_0038.html) 。
- 有关GIN索引的更多示例，请参见[GIN索引使用实践](https://support.huaweicloud.com/bestpractice-dws/dws_05_0025.html)。
#### 常见问题
- [DWS唯一约束和唯一索引有什么区别](https://support.huaweicloud.com/dws_faq/dws_03_1002.html)
- [重建索引失败](https://support.huaweicloud.com/trouble-dws/dws_09_0025.html)
- [修改索引只调用索引名提示索引不存在](https://support.huaweicloud.com/trouble-dws/dws_09_0024.html)
- [DWS元数据不一致-分区索引异常](https://support.huaweicloud.com/trouble-dws/dws_09_0105.html)
- [DWS查询时索引失效场景解析](https://support.huaweicloud.com/dws_faq/dws_03_2105.html)
