云数据库GaussDB创建和管理索引

背景信息

索引可以提高数据的访问速度,但同时也增加了插入、更新和删除操作的处理时间。所以是否要为表增加索引,索引建立在哪些字段上,是创建索引前必须要考虑的问题。需要分析应用程序的业务处理、数据使用、经常被用作查询的条件或者被要求排序的字段来确定是否建立索引。

索引建立在数据库表中的某些列上。因此,在创建索引时,应该仔细考虑在哪些列上创建索引。

1.在经常需要搜索查询的列上创建索引,可以加快搜索的速度。

2.在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构。

3.在经常使用连接的列上创建索引,这些列主要是一些外键,可以加快连接的速度。

4.在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的。

5.在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。

6.在经常使用WHERE子句的列上创建索引,加快条件的判断速度。

7.为经常出现在关键字ORDER BY、GROUP BY、DISTINCT后面的字段建立索引。

说明:索引创建成功后,系统会自动判断何时引用索引。当系统认为使用索引比顺序扫描更快时,就会使用索引。

索引创建成功后,必须和表保持同步以保证能够准确地找到新数据,这样就增加了数据操作的负荷。因此请定期删除无用的索引。

云数据库GaussDB创建索引操作步骤

创建分区表的步骤请参考创建和管理分区表。

创建索引

−创建分区表索引tpcds_web_returns_p2_index1,不指定索引分区的名称。

openGauss=# CREATE INDEX tpcds_web_returns_p2_index1 ON tpcds.web_returns_p2 (ca_address_id) LOCAL;

当结果显示为如下信息,则表示创建成功。

CREATE INDEX

−创建分区表索引tpcds_web_returns_p2_index2,并指定索引分区的名称。

openGauss=# CREATE INDEX tpcds_web_returns_p2_index2 ON tpcds.web_returns_p2 (ca_address_sk) LOCAL

( PARTITION web_returns_p2_P1_index,

   PARTITION web_returns_p2_P2_index TABLESPACE example3,

   PARTITION web_returns_p2_P3_index TABLESPACE example4,

   PARTITION web_returns_p2_P4_index,

   PARTITION web_returns_p2_P5_index,

   PARTITION web_returns_p2_P6_index,

   PARTITION web_returns_p2_P7_index,

   PARTITION web_returns_p2_P8_index ) TABLESPACE example2;

当结果显示为如下信息,则表示创建成功。

CREATE INDEX

修改索引分区的表空间

−修改索引分区web_returns_p2_P2_index的表空间为example1。

openGauss=# ALTER INDEX tpcds.tpcds_web_returns_p2_index2 MOVE PARTITION web_returns_p2_P2_index TABLESPACE example1;

当结果显示为如下信息,则表示修改成功。

ALTER INDEX

−修改索引分区web_returns_p2_P3_index的表空间为example2。

openGauss=# ALTER INDEX tpcds.tpcds_web_returns_p2_index2 MOVE PARTITION web_returns_p2_P3_index TABLESPACE example2;

当结果显示为如下信息,则表示修改成功。

ALTER INDEX

重命名索引分区

执行如下命令对索引分区web_returns_p2_P8_index重命名web_returns_p2_P8_index_new。

openGauss=# ALTER INDEX tpcds.tpcds_web_returns_p2_index2 RENAME PARTITION web_returns_p2_P8_index TO web_returns_p2_P8_index_new;

当结果显示为如下信息,则表示重命名成功。

ALTER INDEX

查询索引

−执行如下命令查询系统和用户定义的所有索引。

openGauss=# SELECT RELNAME FROM PG_CLASS WHERE RELKIND='i';

−执行如下命令查询指定索引的信息。

openGauss=# \di+ tpcds.tpcds_web_returns_p2_index2

删除索引

openGauss=# DROP INDEX tpcds.tpcds_web_returns_p2_index1;

openGauss=# DROP INDEX tpcds.tpcds_web_returns_p2_index2;

当结果显示为如下信息,则表示删除成功。

DROP INDEX

GaussDB支持4种创建索引的方式请参见表1-1。

说明:

索引创建成功后,系统会自动判断何时引用索引。当系统认为使用索引比顺序扫描更快时,就会使用索引。

索引创建成功后,必须和表保持同步以保证能够准确地找到新数据,这样就增加了数据操作的负荷。因此请定期删除无用的索引。

索引方式
描述

唯一索引

可用于约束索引属性值的唯一性,或者属性组合值的唯一性。如果一个表声明了唯一约束或者主键,则GaussDB自动在组成主键或唯一约束的字段上创建唯一索引(可能是多字段索引),以实现这些约束。目前,GaussDB只有B-Tree及UBTree可以创建唯一索引。

多字段索引

一个索引可以定义在表中的多个属性上。目前,GaussDB中的B-Tree支持多字段索引,且最多可在32个字段上创建索引。

部分索引

建立在一个表的子集上的索引,这种索引方式只包含满足条件表达式的元组。

表达式索引

索引建立在一个函数或者从表中一个或多个属性计算出来的表达式上。表达式索引只有在查询时使用与创建时相同的表达式才会起作用。

云数据库GaussDB创建表操作步骤

创建一个普通表

openGauss=# CREATE TABLE tpcds.customer_address_bak AS TABLE tpcds.customer_address;

INSERT 0 0

创建普通索引

如果对于tpcds.customer_address_bak表,需要经常进行以下查询。

openGauss=# SELECT ca_address_sk FROM tpcds.customer_address_bak WHERE ca_address_sk=14888;

通常,数据库系统需要逐行扫描整个tpcds.customer_address_bak表以寻找所有匹配的元组。如果表tpcds.customer_address_bak的规模很大,但满足WHERE条件的只有少数几个(可能是零个或一个),则这种顺序扫描的性能就比较差。如果让数据库系统在ca_address_sk属性上维护一个索引,用于快速定位匹配的元组,则数据库系统只需要在搜索树上查找少数的几层就可以找到匹配的元组,这将会大大提高数据查询的性能。同样,在数据库中进行更新和删除操作时,索引也可以提升这些操作的性能。

使用以下命令创建索引。

openGauss=# CREATE INDEX index_wr_returned_date_skON tpcds.customer_address_bak (ca_address_sk);

CREATE INDEX

创建唯一索引

在表tpcds.ship_mode_t1上的SM_SHIP_MODE_SK字段上创建唯一索引。

openGauss=# CREATE UNIQUE INDEX ds_ship_mode_t1_index1 ON tpcds.ship_mode_t1(SM_SHIP_MODE_SK);

创建多字段索引

假如用户需要经常查询表tpcds.customer_address_bak中ca_address_sk是5050,且ca_street_number小于1000的记录,使用以下命令进行查询。

openGauss=# SELECT ca_address_sk,ca_address_idFROM tpcds.customer_address_bak WHEREca_address_sk = 5050 AND ca_street_number 1000;

使用以下命令在字段ca_address_sk和ca_street_number上定义一个多字段索引。

openGauss=# CREATE INDEX more_column_index ON tpcds.customer_address_bak(ca_address_sk ,ca_street_number );

CREATE INDEX

创建部分索引

如果只需要查询ca_address_sk为5050的记录,可以创建部分索引来提升查询效率。

openGauss=# CREATE INDEX part_index ON tpcds.customer_address_bak(ca_address_sk) WHERE ca_address_sk = 5050;

CREATE INDEX

创建表达式索引

假如经常需要查询ca_street_number小于1000的信息,执行如下命令进行查询。

openGauss=# SELECT * FROM tpcds.customer_address_bakWHERE trunc(ca_street_number) 1000;

可以为上面的查询创建表达式索引:

openGauss=# CREATE INDEX para_index ON tpcds.customer_address_bak (trunc(ca_street_number));

CREATE INDEX

删除tpcds.customer_address_bak表

openGauss=# DROP TABLE tpcds.customer_address_bak;

DROP TABLE

云数据库GaussDB索引约束

使用约束

索引使用满足如下条件时:

1.在同一个表的同一个列上建立了多个gin索引;

2.这些gin索引使用了不同的parser(即分隔符不同);

3.在查询中使用了该列,且执行计划中使用索引进行扫描;

为了避免使用不同gin索引导致查询结果不同的问题,需要保证在物理表的一列上只有一个gin索引可用。

云数据库GaussDB索引设计规范

1.使用数据库索引实践推荐的索引类型。

索引设计建议使用推荐类型,如果需要使用禁用、不推荐、限制使用的索引类型,建议联系GaussDB数据库专家进行评估。

表1-1 数据库索引实践推荐

索引类型
说明
是否推荐

主键/唯一索引

单列或多列主键/唯一索引

推荐

表达式索引

索引列为表的一列或多列计算而来的一个函数或者标量表达式

限制使用

2.对于HASH分布表,主键和唯一索引必须包含分布键。

3.合理设计组合索引,避免冗余。

例如已对(a,b,c)创建索引,则不应再单独对 (a)、(b)、(c)、(a,b)、(b,c)创建索引。

当查询时如果只带有a字段上的过滤条件,一般也会利用组合索引进行查询。

4.不建议单表创建多个唯一索引。

同时维护多个唯一索引的开销远大于维护一个多列唯一索引,如果业务逻辑上多个唯一索引,与一个多列唯一索引等价,应使用多列唯一索引。

5.组合索引字段个数不超过5个。

6.禁止组合索引组合字符串的总长度超过200。

7.索引(包括单列索引和复合索引)字段应为NOT NULL字段。

8.同字段上创建索引的维护效率不同。数值类型字段优于字符类型及其他数据类型,因此对于考虑创建索引的ID、时间等字段,建议使用数值类型进行存储。

9.建议在关联列上创建索引。

GaussDB支持HASH JOIN,但是当内表较小等RESCAN代价较低的情况下,仍然可能选择NESTLOOP JOIN来完成关联。如果通过EXPLAIN可以查看到NESTLOOP JOIN计划,则可以通过在关联列上创建索引,提高NESTLOOP JOIN效率。

专题内容推荐

活动规则

活动对象:华为云电销客户及渠道伙伴客户可参与消费满送活动,其他客户参与前请咨询客户经理

活动时间: 2020年8月12日-2020年9月11日

活动期间,华为云用户通过活动页面购买云服务,或使用上云礼包优惠券在华为云官网新购云服务,累计新购实付付费金额达到一定额度,可兑换相应的实物礼品。活动优惠券可在本活动页面中“上云礼包”等方式获取,在华为云官网直接购买(未使用年中云钜惠活动优惠券)或参与其他活动的订单付费金额不计入统计范围内;