
# CREATE INDEX
#### 功能描述
使用CREATE INDEX可以基于一个外表的一个或多个列建索引。
索引是一个对象，它为索引列的每种取值建立一个记录用来快速找到其对应在外表中的一行或多行。
Aura目前支持的索引是：Lance外表格式的向量索引。
#### 使用限制
- 目前仅支持Lance外表的向量索引。
- 向量索引的算法支持{ivfflat, ivfpq, ivfrq, ivfsq, hnsw, hnswpq, hnswsq}中的任意一种，支持的距离函数为vector_l2_ops \| vector_cosine_ops。
- 每个向量列只能建一种距离的索引，例如vector_l2_ops\|vector_cosine_ops，若用错距离函数，可能影响查询recall。
- 不可以根据相同的索引名（index_name）多次构建索引，重建需要使用ALTER INDEX ... REBUILD语句，该参数需要先删除索引（DROP INDEX）再使用新参数建索引（CREATE INDEX），建议使用IF NOT EXISTS保护，防止多次建同名索引报错。
- NULL向量和有空值的向量将不被索引。
- 不支持double类型，需要使用确定精度浮点向量（array\<float4\>或array\<float8\>）并在建表时利用TBLPROPERTIES指定该向量的维度，例如**TBLPROPERTIES ('arrow.fixed-size-list.size.{nameOfThisVectorColumn}' = '128')，**以防止建索引过程中做其他DDL操作（ALTER COLUMN）。其中float4/8对应float32/64。
 
#### 语法格式
```
CREATE INDEX [ IF NOT EXISTS ] [index_name] ON table_name 
[ USING access_method ]
( col_name opt_opclass [, ...] )
[ WITH ( option_key = option_value [, ... ] ) ];
```
#### 参数说明
- **index_name**：索引名。
- **table_name**：建索引的目标表名。

- **access_method**：索引构建算法，如向量索引的IVFPQ。
  
- **col_name**：建索引的目标列名。
- **opt_opclass**：索引列操作符类别，例如使用cosine距离建索引则为vector_cosine_ops。
- **option_key**：索引参数变量，详细请参见索引参数设置方法。
- **option_value**：索引参数值，详细请参见索引参数设置方法。
表1索引参数设置方法 
| 索引类型          | 参数名（option_key）             | 含义                         | 用法                   | 参考值（option_value）                                                                                   |
|:---|:---|:---|:---|:---|
| ivfflat       | nlists或lists或num_partitions | 聚类分桶数量                     | with (nlists=?)      | num_rows // 4096 或 大表可根据sqrt(num_rows)设置                                                            |
| ivfflat       | sample_rate                 | 为每个中心采样的向量个数               | with (sample_rate=?) | 256, 1024, ... 表需要至少有sample_rate条数据（一个聚类分桶）                                                         |
| ivfflat       | max_iters                   | kmeans聚类时迭代轮数              | with (max_iters=?)   | 25, 50, ...                                                                                         |
| ivfpq         | nlists或lists或num_partitions | 将整个高维向量空间聚类成的簇（cluster）的数量 | with (nlists=?)      | num_rows // 4096 或 大表可根据sqrt(num_rows)设置，另外为提升SIMD执行效率，推荐约束：lists/num_sub_vectors % 8 =0            |
| ivfpq         | num_sub_vectors             | 量化乘积时分解的子向量个数              | with (sub_vectors=?) | dimension // 8 取整，例如{4, 8, 16}，硬约束：num_sub_vectors \< dim (列维数), dimension \<= 256时推荐使用PQ           |
| ivfpq         | sample_rate                 | 求全局聚簇数量和量化子向量聚簇中心时采样的向量个数  | with (sample_rate=?) | 256, 1024, ...; 有约束：num_rows \>=nlists\*sample_rate\^2        |
| ivfpq         | max_iters                   | 求全局聚簇数量和量化子向量聚簇中心时迭代轮数     | with (max_iters=?)   | 25, 50, ...                                                                                         |
| ivfrq         | nlists或lists或num_partitions | 聚类分桶数量                     | with (nlists=?)      | num_rows // 4096 或 大表可根据sqrt(num_rows)设置                                                            |
| ivfrq         | num_bits                    | 量化bit数量                    | with (bits=?)        | 目前仅支持1bit                                                                                           |
| ivfrq         | sample_rate                 | 为每个中心采样的向量个数               | with (sample_rate=?) | 256, 1024, ... 表需要至少有sample_rate条数据（一个聚类分桶）                                                         |
| ivfrq         | max_iters                   | kmeans聚类时迭代轮数              | with (max_iters=?)   | 25, 50, ...                                                                                         |
| ivfsq         | nlists或lists或num_partitions | 聚类分桶数量                     | with (nlists=?)      | num_rows // 4096 或 大表可根据sqrt(num_rows)设置                                                            |
| ivfsq         | num_bits                    | 量化bit数量                    | with (bits=?)        | {4, 8 (default)}                                                                                    |
| ivfsq         | sample_rate                 | 为每个中心采样的向量个数               | with (sample_rate=?) | 256, 1024, ... 表需要至少有sample_rate条数据（一个聚类分桶）                                                         |
| ivfsq         | max_iters                   | kmeans聚类时迭代轮数              | with (max_iters=?)   | 25, 50, ...                                                                                         |
| hnsw/hnswflat | nlists或lists或num_partitions | 聚类分桶数量                     | with (nlists=?)      | num_rows // 1048576 或 大表可根据sqrt(num_rows)设置                                                         |
| hnsw/hnswflat | m                           | hnsw图中每个节点的边数              | with (m=?)           | default 20                                                                                          |
| hnsw/hnswflat | ef或ef_construction          | 建图时的搜索广度                   | with (ef=?)          | \>=150                                                                                              |
| hnsw/hnswflat | sample_rate                 | 为每个中心采样的向量个数               | with (sample_rate=?) | 256, 1024, ... 表需要至少有sample_rate条数据（一个聚类分桶）                                                         |
| hnsw/hnswflat | max_iters                   | kmeans聚类时迭代轮数              | with (max_iters=?)   | 25, 50, ...                                                                                         |
| hnswpq        | nlists或lists或num_partitions | 聚类分桶数量                     | with (nlists=?)      | num_rows // 1048576 或 大表可根据sqrt(num_rows)设置                                                         |
| hnswpq        | m                           | hnsw图中每个节点的边数              | with (m=?)           | default 20                                                                                          |
| hnswpq        | ef或ef_construction          | 建图时的搜索广度                   | with (ef=?)          | \>=150                                                                                              |
| hnswpq        | num_sub_vectors             | 量化乘积时分解的子向量个数              | with (sub_vectors=?) | dimension // 8 取整，例如{4, 8, 16} 硬约束：num_sub_vectors \< dim (列维数) |
| hnswpq        | sample_rate                 | 求全局聚簇数量和量化子向量聚簇中心时采样的向量个数  | with (sample_rate=?) | 256, 1024, ...; 有约束：num_rows \>=nlists\*sample_rate\^2           |
| hnswpq        | max_iters                   | 求全局聚簇数量和量化子向量聚簇中心时迭代轮数     | with (max_iters=?)   | 25, 50, ...                                                                                         |
| hnswsq        | nlists或lists或num_partitions | 聚类分桶数量                     | with (nlists=?)      | num_rows // 1048576 或 大表可根据sqrt(num_rows)设置                                                         |
| hnswsq        | m                           | hnsw图中每个节点的边数              | with (m=?)           | default 20                                                                                          |
| hnswsq        | ef或ef_construction          | 建图时的搜索广度                   | with (ef=?)          | \>=150                                                                                              |
| hnswsq        | num_bits                    | 量化bit数量                    | with (bits=?)        | {4, 8 (default)}                                                                                    |
| hnswsq        | sample_rate                 | 求全局聚簇数量和量化子向量聚簇中心时采样的向量个数  | with (sample_rate=?) | 256, 1024, ...; 有约束：num_rows \>=nlists\*sample_rate\^2          |
| hnswsq        | max_iters                   | 求全局聚簇数量和量化子向量聚簇中心时迭代轮数     | with (max_iters=?)   | 25, 50, ...                                                                                         |
   
#### 示例
为表lance_vector的vector列构建ivfpq的向量索引：
```
create table lance_vector (vector array<float4>) TABLEPROPERTIES ('arrow.fixed-size-list.vector' = '16') store as lance;
CREATE INDEX ix ON lance_vector USING ivfflat (vector vector_cosine_ops) WITH (nlists=2, num_sub_vectors=2);
```
