学习目标
掌握 openGauss DBMS 索引的管理:创建索引、删除索引、查询索引的信息、修改索引的信息。
前面每日一练链接
openGauss 每日一练第 1 天 | openGauss 数据库状态查看
openGauss 每日一练第 2 天 | 学习 gsql 命令行的使用
openGauss 每日一练第 3 天 | openGauss 数据库状态查看
openGauss 每日一练第 4 天 | openGauss 中一个数据库可以被多个用户访问
openGauss 每日一练第 5 天 | openGauss 中一个用户可以访问多个数据库
openGauss 每日一练第 6 天 | openGauss 中用户一次只能连接到一个数据库
openGauss 每日一练第 7 天 | openGauss 中一个数据库中可以创建多个模式
openGauss 每日一练第 8 天 | openGauss 中一个数据库可以存储在多个表空间中
openGauss 每日一练第 9 天 | openGauss 中一个表空间可以存储多个数据库
openGauss 每日一练第 10 天 | openGauss 逻辑结构:表空间管理
openGauss 每日一练第 11 天 | openGauss 逻辑结构:数据库管理
openGauss 每日一练第 12 天 | openGauss 逻辑结构:模式管理
openGauss 每日一练第 13 天 |openGauss 逻辑结构:表管理 1
openGauss 每日一练第 14 天 |openGauss 逻辑结构:表管理 2
openGauss 每日一练第 15 天 |openGauss 逻辑结构:表管理 3
openGauss 每日一练第 16 天 |openGauss 逻辑结构:表管理 4
课程学习
索引是一个指向表中数据的指针。一个数据库中的索引与一本书的索引目录是非常相似的。
索引可以用来提高数据库查询性能,但是不恰当的使用将导致数据库性能下降。
背景信息
索引可以提高数据的访问速度,但同时也增加了插入、更新和删除操作的处理时间。所以是否要为表增加索引,索引建立在哪些字段上,是创建索引前必须要考虑的问题。需要分析应用程序的业务处理、数据使用、经常被用作查询的条件或者被要求排序的字段来确定是否建立索引。
索引建立在数据库表中的某些列上。因此,在创建索引时,应该仔细考虑在哪些列上创建索引。
-
在经常需要搜索查询的列上创建索引,可以加快搜索的速度。
-
在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构。
-
在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的。
-
在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。
-
在经常使用 WHERE 子句的列上创建索引,加快条件的判断速度。
-
为经常出现在关键字 ORDER BY、GROUP BY、DISTINCT 后面的字段建立索引。

索引更多信息参考官方文档 https://docs.opengauss.org/zh/docs/3.1.0/docs/Developerguide/%E5%88%9B%E5%BB%BA%E5%92%8C%E7%AE%A1%E7%90%86%E7%B4%A2%E5%BC%95.html
1.创建索引
--为表 test 的 testnum 列创建一个索引
gsql -d omm -p 5432 -r
gsql ((openGauss 3.1.0 build 4e931f9a) compiled at 2022-09-29 14:19:24 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
create table test(id serial primary key,testnum serial);
create index idx_test_testnum on test(testnum);
--查看索引
\di

2.通过 hint 使用索引
--测试准备,创建表 customer,并插入数据
CREATE TABLE customer
(
ca_address_sk integer NOT NULL ,
ca_address_id character(16),
ca_street_number character(10) ,
ca_street_name character varying(60) ,
ca_street_type character(15) ,
ca_suite_number character(10) ,
ca_city character varying(60) ,
ca_county character varying(30) ,
ca_state character(2) ,
ca_zip character(10) ,
ca_country character varying(20) ,
ca_gmt_offset numeric(5,2) ,
ca_location_type character(20)
);
insert into customer values
(1, 'AAAAAAAABAAAAAAA', '18', 'Jackson', 'Parkway', 'Suite 280', 'Fairfield', 'Maricopa County', 'AZ', '86192' ,'United States', -7.00, 'condo'),
(2, 'AAAAAAAACAAAAAAA', '362', 'Washington 6th', 'RD', 'Suite 80', 'Fairview', 'Taos County', 'NM', '85709', 'United States', -7.00, 'condo'),
(3, 'AAAAAAAADAAAAAAA', '585', 'Dogwood Washington', 'Circle', 'Suite Q', 'Pleasant Valley', 'York County', 'PA', '12477', 'United States', -5.00, 'single family');

创建索引
create index customer_idx on customer(ca_address_sk);
--通过 hint 强制使用索引,查看执行计划
EXPLAIN SELECT /*+ indexscan(customer customer_idx ) */
* FROM customer WHERE ca_address_sk<100;
omm=# create index customer_idx on customer(ca_address_sk);
CREATE INDEX
omm=# EXPLAIN SELECT /*+ indexscan(customer customer_idx ) */
omm-# * FROM customer WHERE ca_address_sk<100;
QUERY PLAN
-------------------------------------------------------------------------------
[Bypass]
Index Scan using customer_idx on customer (cost=0.00..8.27 rows=1 width=280)
Index Cond: (ca_address_sk < 100)
(3 rows)

3.rename 索引
ALTER INDEX idx_test_testnum RENAME TO idx_test_testnum_new;
omm=# select * from pg_indexes where tablename='test';
schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+----------------------+------------+--------------------------------------------------------------------
------------------
public | test | test_pkey | | CREATE UNIQUE INDEX test_pkey ON test USING btree (id) TABLESPACE j
ieke_tbs
public | test | idx_test_testnum_new | | CREATE INDEX idx_test_testnum_new ON test USING btree (testnum) TAB
LESPACE jieke_tbs
(2 rows)

4.重建索引
--重建一个单独索引
ALTER INDEX idx_test_testnum_new REBUILD;
REINDEX INDEX idx_test_testnum_new;
--重建所有索引
reindex table test;

5.移动索引到其他表空间
--创建表空间 myindex_ts:
CREATE TABLESPACE myindex_ts RELATIVE LOCATION 'tablespace/myindex_ts';
--将索引 idx_test_testnum_new 移动到表空间 myindex_ts:
ALTER INDEX idx_test_testnum_new SET TABLESPACE myindex_ts;
--查看索引所在的表空间
select * from pg_indexes where tablename = 'test';
--或
omm=# select * from pg_indexes where indexname = 'idx_test_testnum_new';
schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+----------------------+------------+--------------------------------------------------------------------
-------------------
public | test | idx_test_testnum_new | myindex_ts | CREATE INDEX idx_test_testnum_new ON test USING btree (testnum) TAB
LESPACE myindex_ts
(1 row)

6.删除索引
--执行下面的命令,删除表 test 上的索引 idx_test_testnum_new:
drop index idx_test_testnum_new;
课程作业
1.创建表,在表中创建索引
omm=# create table jieke(id serial primary key,name varchar(30));
NOTICE: CREATE TABLE will create implicit sequence "jieke_id_seq" for serial column "jieke.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "jieke_pkey" for table "jieke"
CREATE TABLE
omm=# create index idx_jieke_name on jieke(name);
CREATE INDEX
omm=# \di
List of relations
Schema | Name | Type | Owner | Table | Storage
--------+----------------------+-------+-------+----------+---------
public | customer_idx | index | omm | customer |
public | idx_jieke_name | index | omm | jieke |
public | idx_test_testnum_new | index | omm | test |
public | jieke_pkey | index | omm | jieke |
public | t1_pkey | index | omm | t1 |
public | t2_pkey | index | omm | t2 |
public | t3_pkey | index | omm | t3 |
public | t4_pkey | index | omm | t4 |
public | test001_pkey | index | omm | test001 |
public | test002_pkey | index | omm | test002 |
public | test_pkey | index | omm | test |
(11 rows)
2.通过 hint 使用索引
omm=# insert into jieke values(1,'Bob'),(2,'Dod'),(3,'Scott'),(4,'Mali'),(5,'Lili');
INSERT 0 5
omm=# explain select /*+ indexscan(jieke idx_jieke_name) */ * from jieke;
WARNING: unused hint: IndexScan(jieke idx_jieke_name)
QUERY PLAN
----------------------------------------------------------
Seq Scan on jieke (cost=0.00..22.19 rows=1219 width=37)
(1 row)
omm=# explain select /*+ indexscan(jieke idx_jieke_name) */ * from jieke where name like 'Li%';
QUERY PLAN
------------------------------------------------------------------------------
Index Scan using idx_jieke_name on jieke (cost=0.00..24.38 rows=6 width=37)
Index Cond: (((name)::text >= 'Li'::text) AND ((name)::text < 'Lj'::text))
Filter: ((name)::text ~~ 'Li%'::text)
(3 rows)
omm=# select * from jieke where name like 'Li%';
id | name
----+------
5 | Lili
(1 row)
omm=# explain select /*+ indexscan(jieke idx_jieke_name) */ * from jieke where id <=4;
WARNING: unused hint: IndexScan(jieke idx_jieke_name)
QUERY PLAN
---------------------------------------------------------------------------
Bitmap Heap Scan on jieke (cost=7.40..22.47 rows=406 width=37)
Recheck Cond: (id <= 4)
-> Bitmap Index Scan on jieke_pkey (cost=0.00..7.29 rows=406 width=0)
Index Cond: (id <= 4)
(4 rows)
omm=# explain select /*+ indexscan(jieke jieke_pkey) */ * from jieke where id <=4;
QUERY PLAN
----------------------------------------------------------------------------
[Bypass]
Index Scan using jieke_pkey on jieke (cost=0.00..51.36 rows=406 width=37)
Index Cond: (id <= 4)
(3 rows)
omm=# select * from jieke where id <=4;
id | name
----+-------
1 | Bob
2 | Dod
3 | Scott
4 | Mali
(4 rows)

3.rename 索引
select * from pg_indexes where tablename='jieke';
alter index idx_jieke_name rename to jiek_name_idx;
select * from pg_indexes where tablename='jieke';
omm=# select * from pg_indexes where tablename='jieke';
schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+---------------+------------+---------------------------------------------------------------------------
----
public | jieke | jieke_pkey | | CREATE UNIQUE INDEX jieke_pkey ON jieke USING btree (id) TABLESPACE jieke_
tbs
public | jieke | jiek_name_idx | | CREATE INDEX jiek_name_idx ON jieke USING btree (name) TABLESPACE jieke_tb
s
(2 rows)
4.重建索引
alter index jiek_name_idx rebuild;
reindex index jiek_name_idx;
reindex table jieke;

5.移动索引到其他表空间
alter index jiek_name_idx set tablespace myindex_ts;
omm=# \db
List of tablespaces
Name | Owner | Location
------------+-------+-----------------------
jieke_tbs | omm | tablespace/jieke_tbs
myindex_ts | omm | tablespace/myindex_ts
pg_default | omm |
pg_global | omm |
(4 rows)
omm=# \di
List of relations
Schema | Name | Type | Owner | Table | Storage
--------+----------------------+-------+-------+----------+---------
public | customer_idx | index | omm | customer |
public | idx_test_testnum_new | index | omm | test |
public | jiek_name_idx | index | omm | jieke |
public | jieke_pkey | index | omm | jieke |
public | t1_pkey | index | omm | t1 |
public | t2_pkey | index | omm | t2 |
public | t3_pkey | index | omm | t3 |
public | t4_pkey | index | omm | t4 |
public | test001_pkey | index | omm | test001 |
public | test002_pkey | index | omm | test002 |
public | test_pkey | index | omm | test |
(11 rows)
omm=# \di+ jiek_name_idx
List of relations
Schema | Name | Type | Owner | Table | Size | Storage | Description
--------+---------------+-------+-------+-------+-------+---------+-------------
public | jiek_name_idx | index | omm | jieke | 16 kB | |
(1 row)
omm=# select * from pg_indexes where indexname = 'jiek_name_idx';
schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+---------------+------------+---------------------------------------------------------------------------
--
public | jieke | jiek_name_idx | | CREATE INDEX jiek_name_idx ON jieke USING btree (name) TABLESPACE jieke_tb
s
(1 row)
omm=# alter index jiek_name_idx set tablespace myindex_ts;
ALTER INDEX
omm=# select * from pg_indexes where indexname = 'jiek_name_idx';
schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+---------------+------------+---------------------------------------------------------------------------
---
public | jieke | jiek_name_idx | myindex_ts | CREATE INDEX jiek_name_idx ON jieke USING btree (name) TABLESPACE myindex_
ts
(1 row)

6.删除索引
drop index jiek_name_idx;
欢迎关注我的公众号【JiekeXu DBA之路】,第一时间一起学习新知识!
————————————————————————————
公众号:JiekeXu DBA之路
CSDN :https://blog.csdn.net/JiekeXu
墨天轮:https://www.modb.pro/u/4347
腾讯云:https://cloud.tencent.com/developer/user/5645107
————————————————————————————





