REINDEX — 重建索引
REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } name
   REINDEX使用索引的表里存储的数据重建一个索引,
   并且替换该索引的旧拷贝。有一些场景需要使用REINDEX:
   
      一个索引已经损坏,并且不再包含合法数据。尽管理论上这不会发生,
      实际上索引会因为软件缺陷或硬件失效损坏。
      REINDEX提供了一种恢复方法。
     
      一个索引变得“臃肿”,其中包含很多空的或者近乎为空的页面。
      PostgreSQL中的 B-树索引在特定的非
      常规访问模式下可能会发生这种情况。REINDEX
      提供了一种方法来减少索引的空间消耗,即制造一个新版本的索引,其中没有
      死亡页面。详见Section 24.2。
     
修改了一个索引的存储参数(例如填充因子),并且希望确保这种修改完全 生效。
      用CONCURRENTLY选项进行的一次索引创建失败,留下了
      一个“无效的”索引。这类索引是没有用处的,但是可以用
      REINDEX来重建它们。注意,
      REINDEX将不会执行一次并发构建。要构建该索引并且
      不干扰生产,应该先删除索引并且重新发出
      CREATE INDEX CONCURRENTLY命令。
     
INDEX重新创建指定的索引。
TABLE重新创建指定表的所有索引。如果该表有一个二级 “TOAST”表,它也会被重索引。
SCHEMA
      重建指定方案的所有索引。如果这个方案中的一个表有次级的“TOAST”表,它也会被重建索引。共享系统目录上的索引也会被处理。这种形式的REINDEX不能在事务块内执行。
     
DATABASE
      重新创建当前数据库内的所有索引。共享的系统目录上的索引也会被
      处理。这种形式的REINDEX不能在一个
      事务块内执行。
     
SYSTEM
      重新创建当前数据库中在系统目录上的所有索引。共享系统目录上的
      索引也被包括在内。用户表上的索引则不会被处理。这种形式的
      REINDEX不能在一个事务块内执行。
     
name
      要被重索引的特定索引、表或者数据库的名字。索引和表名可以被
      模式限定。当前,REINDEX DATABASE和
      REINDEX SYSTEM只能重索引当前数据库,因此
      它们的参数必须匹配当前数据库的名称。
     
VERBOSE在每个索引被重建时打印进度报告。
   如果怀疑一个用户表上的索引损坏,可以使用
   REINDEX INDEX或者
   REINDEX TABLE简单地重建该索引
   或者表上的所有索引。
  
   如果你需要从一个系统表上的索引损坏中恢复,就更困难一些。在
   这种情况下,对系统来说重要的是没有使用过任何可疑的索引本身(
   实际上,这种场景中,你可能会发现服务器进程会在启动时立刻崩溃,
   这是因为对于损坏的索引的依赖)。要安全地恢复,服务器必须用
   -P选项启动,这将阻止它使用索引来进行系统
   目录查找。
  
   这样做的一种方法是关闭服务器,并且启动一个单用户的
   PostgreSQL服务器,在其命令行
   中包括-P选项。然后,可以发出
   REINDEX DATABASE、REINDEX SYSTEM、
   REINDEX TABLE或者REINDEX INDEX,
   具体使用哪个命令取决于你想要重构多少东西。如果有疑问,可以使用
   REINDEX SYSTEM来选择重建数据库中的所有系统索引。
   然后退出单用户服务器会话并且重启常规的服务器。更多关于如何与
   单用户服务器接口交互的内容请见postgres参考页。
  
   在另一种方法中,可以开始一个常规的服务器会话,在其命令行选项
   中包括-P。这样做的方法与客户端有关,但是在
   所有基于libpq的客户端中都可以在开始客户端
   之前设置PGOPTIONS环境变量为-P。
   注意虽然这种方法不要求用锁排斥其他客户端,在修复完成之前避免
   其他用户连接到受损的数据库才是更加明智的。
  
   REINDEX类似于删除索引并且重建索引,在其中
   索引内容会被从头开始建立。不过,锁定方面的考虑却相当不同。
   REINDEX会用锁排斥写,但不会排斥在索引的父表上的读。
   它也会在被处理的索引上取得一个排他锁,该锁将会阻塞对该索引的使用尝试。
   相反,DROP INDEX 会暂时在附表上取得一个排他锁,阻塞
   写和读。后续的CREATE INDEX会排斥写但不排斥读,由于
   该索引不存在,所以不会有读取它的尝试,这意味着不会有阻塞但是读操作可能
   被强制成昂贵的顺序扫描。
  
   重索引单独一个索引或者表要求用户是该索引或表的拥有者。对方案或数据库重建索引要求是该方案或者数据库的拥有者。注意因此非超级用户有时无法重建其他用户拥有的表上的索引。不过,作为一种特例,当一个非超级用户发出REINDEX DATABASE、REINDEX SCHEMA或者REINDEX SYSTEM时,共享目录上的索引将被跳过,除非该用户拥有该目录(通常不会是这样)。当然,超级用户总是可以重建所有的索引。
  
不支持重建分区表的索引或者分区索引。不过可以单独为每个分区重建索引。
重建单个索引:
REINDEX INDEX my_index;
   重建表my_table上的所有索引:
REINDEX TABLE my_table;
重建一个特定数据库中的所有索引,且不假设系统索引已经可用:
$export PGOPTIONS="-P"$psql broken_db... broken_db=> REINDEX DATABASE broken_db; broken_db=> \q
   在 SQL 标准中没有REINDEX命令。