Creating and Managing Indexes
Tags: opengauss
Published: 2023-04-13 02:39:10

Background
Indexes accelerate data access but increase the processing time of insertion, update, and deletion operations. Therefore, before creating an index, consider whether it is necessary and determine the columns where the index will be created. You can determine whether to add an index for a table by analyzing the service processing and data use of applications, as well as columns that are frequently used as search criteria or need to be collated.

Indexes are created based on columns in database tables. Therefore, you must correctly identify which columns require indexes. You are advised to create indexes for any of the following columns:

Columns that are often searched and queried. This speeds up searches.

Columns that function as primary keys. This enforces the uniqueness of the columns and the data collation structures in organized tables.

Columns that are often searched by range. The index helps collate data, and therefore the specified ranges are contiguous.

Columns that often need to be collated. The index helps collate data, reducing the time for a collation query.

Columns where the WHERE clause is executed frequently. This speeds up condition judgment.

Columns that often appear after the keywords ORDER BY, GROUP BY, and DISTINCT.

 NOTE:

After an index is created, the system automatically determines when to reference it. If the system determines that indexing is faster than sequenced scanning, the index will be used.
After an index is successfully created, it must be synchronized with the associated table to ensure new data can be accurately located, which increases the data operation load. Therefore, delete unnecessary indexes periodically.
Partitioned table indexes are classified into LOCAL indexes and GLOBAL indexes. A LOCAL index corresponds to a specific partition, and a GLOBAL index corresponds to the entire partitioned table.
Procedure
For details about how to create a partitioned table, see Creating and Managing Partitioned Tables.

Creating an index

Create the LOCAL index tpcds_web_returns_p2_index1 without specifying the partition name for a partitioned table.

""
postgres=# CREATE INDEX tpcds_web_returns_p2_index1 ON tpcds.web_returns_p2 (ca_address_id) LOCAL;
If the following information is displayed, the table has been created:

""
CREATE INDEX
Create the LOCAL index tpcds_web_returns_p2_index2 with the partition name specified for a partitioned table.

""
postgres=# 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;
If the following information is displayed, the table has been created:

""
CREATE INDEX
Create the GLOBAL index tpcds_web_returns_p2_global_index for a partitioned table.

""
CREATE INDEX tpcds_web_returns_p2_global_index ON tpcds.web_returns_p2 (ca_street_number) GLOBAL;
Modifying the tablespace of an index partition

Change the tablespace of index partition web_returns_p2_P2_index to example1.

""
postgres=# ALTER INDEX tpcds.tpcds_web_returns_p2_index2 MOVE PARTITION web_returns_p2_P2_index TABLESPACE example1;
If the following information is displayed, the tablespace of the index partition has been modified:

""
ALTER INDEX
Change the tablespace of index partition web_returns_p2_P3_index to example2.

""
postgres=# ALTER INDEX tpcds.tpcds_web_returns_p2_index2 MOVE PARTITION web_returns_p2_P3_index TABLESPACE example2;
If the following information is displayed, the tablespace of the index partition has been modified:

""
ALTER INDEX
Renaming an index partition

Rename the name of index partition web_returns_p2_P8_index to web_returns_p2_P8_index_new.

""
postgres=# ALTER INDEX tpcds.tpcds_web_returns_p2_index2 RENAME PARTITION web_returns_p2_P8_index TO web_returns_p2_P8_index_new;
If the following information is displayed, the index partition has been renamed:

""
ALTER INDEX
Querying indexes

Run the following command to query all indexes defined by the system and users:

""
postgres=# SELECT RELNAME FROM PG_CLASS WHERE RELKIND='i' or RELKIND='I';
Run the following command to query information about a specified index:

""
postgres=# \di+ tpcds.tpcds_web_returns_p2_index2 
Dropping an index

""
postgres=# DROP INDEX tpcds.tpcds_web_returns_p2_index1;
postgres=# DROP INDEX tpcds.tpcds_web_returns_p2_index2;
If the following information is displayed, the tables have been deleted:

""
DROP INDEX
openGauss supports four methods for creating indexes. For details, see Table 1.

 NOTE:

After an index is created, the system automatically determines when to reference it. If the system determines that indexing is faster than sequenced scanning, the index will be used.
After an index is successfully created, it must be synchronized with the associated table to ensure new data can be accurately located, which increases the data operation load. Therefore, delete unnecessary indexes periodically.
Table 1 Indexing methods


Indexing Method

Description

Unique index

An index that requires the uniqueness of an index attribute or an attribute group. If a table declares unique constraints or primary keys, openGauss automatically creates unique indexes (or composite indexes) for columns that form the primary keys or unique constraints. Currently, unique indexes can be created only for B-tree in openGauss.

Composite index

An index that can be defined for multiple attributes of a table. Currently, composite indexes can be created only for B-tree in openGauss and up to 32 columns (Global partition index supports up to 31 columns) can share a composite index.

Partial index

An index that can be created for subsets of a table. This indexing method contains only tuples that meet condition expressions.

Expression index

An index that is built on a function or expression calculated based on one or more attributes of a table. An expression index works only when the queried expression is the same as the created expression.

Create an ordinary table.

""
postgres=# CREATE TABLE tpcds.customer_address_bak AS TABLE tpcds.customer_address;
INSERT 0 0
Create an ordinary index.

For the tpcds.customer_address_bak table, you need to perform the following operations frequently:

""
postgres=# SELECT ca_address_sk FROM tpcds.customer_address_bak WHERE ca_address_sk=14888;
Generally, the database system needs to scan the tpcds.customer_address_bak table row by row to find all matched tuples. If the size of the tpcds.customer_address_bak table is large but only a few (possibly zero or one) of the WHERE conditions are met, the performance of this sequential scan is low. If the database system uses an index to maintain the ca_address_sk attribute, the database system only needs to search a few tree layers for the matched tuples. This greatly improves data query performance. Furthermore, indexes can improve the update and deletion operation performance in the database.

Run the following command to create an index:

""
postgres=# CREATE INDEX index_wr_returned_date_sk ON tpcds.customer_address_bak (ca_address_sk);
CREATE INDEX
Create a multi-column index.

Assume you need to frequently query records with ca_address_sk being 5050 and ca_street_number smaller than 1000 in the tpcds.customer_address_bak table. Run the following commands:

""
postgres=# SELECT ca_address_sk,ca_address_id FROM tpcds.customer_address_bak WHERE ca_address_sk = 5050 AND ca_street_number < 1000;
Run the following command to define a composite index on ca_address_sk and ca_street_number columns:

""
postgres=# CREATE INDEX more_column_index ON tpcds.customer_address_bak(ca_address_sk ,ca_street_number );
CREATE INDEX
Create a partial index.

If you only want to find records whose ca_address_sk is 5050, you can create a partial index to facilitate your query.

""
postgres=# CREATE INDEX part_index ON tpcds.customer_address_bak(ca_address_sk) WHERE ca_address_sk = 5050;
CREATE INDEX
Create an expression index.

Assume that you need to frequently query records with ca_street_number smaller than 1000, run the following command:

""
postgres=# SELECT * FROM tpcds.customer_address_bak WHERE trunc(ca_street_number) < 1000;
The following expression index can be created for this query task:

""
postgres=# CREATE INDEX para_index ON tpcds.customer_address_bak (trunc(ca_street_number));
CREATE INDEX
Delete the tpcds.customer_address_bak table.

""
postgres=# DROP TABLE tpcds.customer_address_bak;
DROP TABLE