
# REINDEX
#### 功能描述
为表中的数据重建索引。
在以下几种情况下需要使用REINDEX重建索引：
- 索引崩溃，并且不再包含有效的数据。
- 索引变得"臃肿"，包含大量的空页或接近空页。
- 为索引更改了存储参数（例如填充因子），并且希望这个更改完全生效。
- 使用CONCURRENTLY选项创建索引失败，留下了一个"非法"索引。
 
#### 注意事项
- REINDEX DATABASE和SYSTEM这种形式的重建索引不能在事务块中执行。目前不支持对物化视图进行REINDEX操作。
- REINDEX CONCURRENTLY在线重建索引导致表上索引顺序改变时，可能会导致查询计划改变。
 
#### 语法格式
- 重建普通索引。
  ```
  REINDEX { INDEX | TABLE | DATABASE | SYSTEM } [CONCURRENTLY] name [ FORCE ];
  ```
  

- 重建索引分区。
  ```
  REINDEX  { INDEX|  TABLE} name
      PARTITION partition_name [ FORCE  ];
  ```
  
 
#### 参数说明
- **INDEX**
  重新建立指定的索引。
  
- **TABLE**
  重新建立指定表的所有索引，如果表有从属的"TOAST"表，则这个表也会重建索引。如果表上有索引已经被alter unusable失效，则这个索引无法被重新创建。当指定CONCURRENTLY选项时，暂不支持重建从属"TOAST"表上的索引。
  
- **DATABASE**
  重建当前数据库里的所有索引。当指定CONCURRENTLY选项时，暂不支持重建数据库中表的从属"TOAST"表上的索引。
  
- **SYSTEM**
  在当前数据库上重建所有系统表上的索引。不会处理在用户表上的索引。
  
- **CONCURRENTLY**
  以不阻塞DML的方式重建索引（加ShareUpdateExclusiveLock锁）。重建索引时，一般会阻塞其他语句对该索引所依赖表的访问。指定此关键字，可以实现重建过程中不阻塞DML。不支持在线重建系统表上的索引。不支持REINDEX INTERNAL TABLE CONCURRENTLY和REINDEX SYSTEM CONCURRENTLY。当执行REINDEX DATABASE CONCURRENTLY时，在线重建当前数据库中用户表上的所有索引（不会处理系统表上的索引）。REINDEX CONCURRENTLY不可以在事务内执行。在线重建索引只支持B-tree索引和UB-tree索引，只支持普通索引、GLOBAL索引、LOCAL索引。在线并行重建索引只支持Astore的普通索引、GLOBAL索引、LOCAL索引，Ustore索引不支持在线并行重建。如果在线重建索引失败，可能会留下非法的新索引，在系统无法自动清理失败新索引的情况下（比如数据库宕机），需要尽快手动清除（使用DROP INDEX语句）非法新索引，以防占用更多资源。一般来说，非法的新索引的后缀名为_ccnew。REINDEX INDEX CONCURRENTLY对表加4级会话锁，且其前几个阶段与CREATE INDEX CONCURRENTLY相似，因此也可能产生卡住或死锁的问题，具体场景与CREATE INDEX CONCURRENTLY相似（比如两个会话同时对同一个索引或表进行REINDEX CONCURRENTLY操作，会引发死锁问题），详见[CONCURRENTLY](https://support.huaweicloud.com/centralized-devg-v3-gaussdb/gaussdb-42-0537.html#ZH-CN_TOPIC_0000002200579046__zh-cn_topic_0000002235221393_li1664032114110)章节。
  
- **name**
  需要重建索引的索引、表、数据库的名称。表和索引可以有模式修饰。
  ![](https://support.huaweicloud.com/centralized-devg-v3-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  REINDEX DATABASE和SYSTEM只能重建当前数据库的索引，所以name必须和当前数据库名称相同。
  
- **FORCE**
  废弃选项，仅为保持前向兼容，故继续保留。
  
- **partition_name**
  需要重建索引的分区的名称或者索引分区的名称。
  取值范围：
  - 如果前面是REINDEX INDEX，则这里应该指定索引分区的名称；
  
  - 如果前面是REINDEX TABLE，则这里应该指定分区的名称；
   
![](https://support.huaweicloud.com/centralized-devg-v3-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
REINDEX DATABASE和SYSTEM这种形式的重建索引不能在事务块中执行。
#### 示例
```
--创建SCHEMA。
gaussdb=# CREATE SCHEMA tpcds;
--创建表tpcds. customer。
gaussdb=# CREATE TABLE tpcds.customer
(
c_customer_sk         INTEGER        NOT NULL,
c_customer_id         CHAR(16)       NOT NULL
);
--向表中插入多条记录。
gaussdb=# INSERT INTO tpcds.customer VALUES (1, 'AAAAAAAABAAAAAAA'),(5, 'AAAAAAAACAAAAAAA'),(10, 'AAAAAAAADAAAAAAA');
--创建一个行存表tpcds.customer_t1，并在tpcds.customer_t1表上的c_customer_sk字段创建索引。
gaussdb=# CREATE TABLE tpcds.customer_t1
(
    c_customer_sk             integer               not null,
    c_customer_id             char(16)              not null,
    c_current_cdemo_sk        integer                       ,
    c_current_hdemo_sk        integer                       ,
    c_current_addr_sk         integer                       ,
    c_first_shipto_date_sk    integer                       ,
    c_first_sales_date_sk     integer                       ,
    c_salutation              char(10)                      ,
    c_first_name              char(20)                      ,
    c_last_name               char(30)                      ,
    c_preferred_cust_flag     char(1)                       ,
    c_birth_day               integer                       ,
    c_birth_month             integer                       ,
    c_birth_year              integer                       ,
    c_birth_country           varchar(20)                   ,
    c_login                   char(13)                      ,
    c_email_address           char(50)                      ,
    c_last_review_date        char(10)
)
WITH (orientation = row);
gaussdb=# CREATE INDEX tpcds_customer_index1 ON tpcds.customer_t1 (c_customer_sk);
gaussdb=# INSERT INTO tpcds.customer_t1 SELECT * FROM tpcds.customer WHERE c_customer_sk < 10;
--重建一个单独索引。
gaussdb=# REINDEX INDEX tpcds.tpcds_customer_index1;
--在线重建一个单独索引。
gaussdb=# REINDEX INDEX CONCURRENTLY tpcds.tpcds_customer_index1;
--重建表tpcds.customer_t1上的所有索引。
gaussdb=# REINDEX TABLE tpcds.customer_t1;
--在线重建表tpcds.customer_t1上的所有索引。
gaussdb=# REINDEX TABLE CONCURRENTLY tpcds.customer_t1;
--删除tpcds.customer_t1表。
gaussdb=# DROP TABLE tpcds.customer_t1;
--删除表。
gaussdb=# DROP TABLE tpcds.customer;
--删除SCHEMA。
gaussdb=# DROP SCHEMA tpcds CASCADE;
```
#### 优化建议
- DATABASE 不能在事务中reindex database。
  
- SYSTEM 不能在事务中reindex系统表。
  
 
