openGauss源码解析(173)
openGauss源码解析:AI技术(20)
8.4.5 使用示例
1. 单条查询语句的索引推荐
单条查询语句的索引推荐功能支持用户在数据库中直接进行操作,本功能基于查询语句的语义信息和数据库的统计信息,对用户输入的单条查询语句生成推荐的索引。本功能涉及的函数接口如表8-9所示。
表8-9 单query索引推荐功能的函数接口
函数名 | 参数 | 返回值 | 功能 |
gs_index_advise | SQL语句字符串 | 无 | 针对单条查询语句生成推荐索引(该版本只支持B树索引) |
使用上述函数,获取针对该query生成的推荐索引,推荐结果由索引的表名和列名组成。
opengauss=> select * from gs_index_advise('SELECT c_discount from bmsql_customer where c_w_id = 10');
table | column
----------------+----------
bmsql_customer | (c_w_id)
(1 row)
上述结果表明:应当在bmsql_customer的c_w_id列上创建索引,例如可以通过下述SQL语句创建索引。
CREATE INDEX idx on bmsql_customer(c_w_id);
某些SQL语句,也可能被推荐创建联合索引,例如:
opengauss=# select * from gs_index_advise('select name, age, sex from t1 where age >= 18 and age < 35 and sex = ''f'';');
table | column
-------+------------
t1 | (age, sex)
(1 row)
上述语句结果表明应该在表t1上创建一个联合索引(age, sex),可以通过下述命令创建该索引,并将其命名为idx1。
CREATE INDEX idx1 on t1(age, sex);
2. 虚拟索引
虚拟索引功能支持用户在数据库中直接进行操作,该功能模拟真实索引的建立,避免真实索引创建所需的时间和空间开销,用户基于虚拟索引,可通过优化器评估该索引对指定查询语句的代价影响。
虚拟索引功能涉及的系统函数接口如表8-10所示。
表8-10 虚拟索引功能的接口
函数名 | 参数 | 返回值 | 功能 | |
hypopg_create_index | 创建索引语句的字符串 | 无 | 创建虚拟索引 | |
hypopg_display_index | 无 | 结果集 | 显示所有创建的虚拟索引信息 | |
hypopg_drop_index | 索引的oid | 无 | 删除指定的虚拟索引 | |
hypopg_reset_index | 无 | 无 | 清除所有虚拟索引 | |
hypopg_estimate_size | 索引的oid | 整数型 | 估计指定索引创建所需的空间大小 |
本功能涉及的GUC参数如表8-11所示。
表8-11 GUC参数
参数名 | 级别 | 功能 | 类型 | 默认值 |
enable_hypo_index | PGC_USERSET | 是否开启虚拟索引功能 | bool | off |
(1) 使用hypopg_create_index函数创建虚拟索引。例如:
opengauss=> select * from hypopg_create_index('create index on bmsql_customer(c_w_id)');
indexrelid | indexname
------------+-------------------------------------
329726 | <329726>btree_bmsql_customer_c_w_id
(1 row)
(2) 开启GUC参数enable_hypo_index,该参数控制数据库的优化器进行EXPLAIN时是否考虑创建的虚拟索引。通过对特定的查询语句执行explain,用户可根据优化器给出的执行计划评估该索引是否能够提升该查询语句的执行效率。例如:
opengauss=> set enable_hypo_index = on;
SET
开启GUC参数前,执行EXPLAIN+查询语句,如下所示:
opengauss=> explain SELECT c_discount from bmsql_customer where c_w_id = 10;
QUERY PLAN
--------------------------------------------------------------------
Seq Scan on bmsql_customer (cost=0.00..52963.06 rows=31224 width=4)
Filter: (c_w_id = 10)
(2 rows)
开启GUC参数后,执行EXPLAIN+查询语句,如下所示:
opengauss=> explain SELECT c_discount from bmsql_customer where c_w_id = 10;
QUERY PLAN
--------------------------------------------------------------------
[Bypass]
Index Scan using <329726>btree_bmsql_customer_c_w_id on bmsql_customer (cost=0.00..39678.69 rows=31224 width=4)
Index Cond: (c_w_id = 10)
(3 rows)
通过对比两个执行计划可以观察到,该索引预计会降低指定查询语句的执行代价,用户可考虑创建对应的真实索引。
(3) (可选)使用hypopg_display_index函数展示所有创建过的虚拟索引。例如:
opengauss=> select * from hypopg_display_index();
indexname | indexrelid | table | column
--------------------------------------------+------------+----------------+------------------
<329726>btree_bmsql_customer_c_w_id | 329726 | bmsql_customer | (c_w_id)
<329729>btree_bmsql_customer_c_d_id_c_w_id | 329729 | bmsql_customer | (c_d_id, c_w_id)
(2 rows)
(4) (可选)使用hypopg_estimate_size函数估计虚拟索引创建所需的空间大小(单位:字节)。例如:
opengauss=> select * from hypopg_estimate_size(329730);
hypopg_estimate_size
----------------------
15687680
(1 row)
(5) 删除虚拟索引。
① 使用hypopg_drop_index函数删除指定oid的虚拟索引。例如:
opengauss=> select * from hypopg_drop_index(329726);
hypopg_drop_index
-------------------
t
(1 row)
② 使用hypopg_reset_index函数一次性清除所有创建的虚拟索引。例如:
opengauss=> select * from hypopg_reset_index();
hypopg_reset_index
--------------------
(1 row)