OceanBase v4.3 特性解读:如何监控索引的使用?

2024年 5月 10日 37.0k 0

写在前面

当我们执行数据库查询时,我们总是希望结果能够迅速返回。在众多提高查询速度的方法中,使用索引是最普遍的一种。一般来说,索引能够显著地提升查询效率。然而,并不是每一个索引都会起到预期的效果,这可能与索引的建立策略有关,或者与 OceanBase 的成本评估模型相关。

在大量的查询中,我们可能会遇到一些低效的索引,甚至是那些根本不被利用的索引。这些“无效”索引占据了宝贵的存储空间和内存资源,造成了不必要的浪费。因此,识别这些索引并对其进行优化或移除,是维持数据库效率和资源合理利用的重要步骤。

如何使用

OceanBase 索引监控功能已默认激活,且无需用户进行任何额外配置或操作即可使用。为了使监控结果可查询,我们引入了租户级别的视图。此外,我们也提供了租户级别的隐藏配置项,以便用户可以自定义监控设置。值得注意的是,这些配置项及数据的汇总是针对各个租户独立的,互不影响。

当前,我们的关注点主要是识别和排除用户租户中的无效索引,因此监控数据的统计仅限于用户租户,不涉及系统租户。这一点在使用时需要特别留意。

配置项说明

OceanBase 4.3 提供了隐藏配置项来自定义监控设置。虽然 show parameters 无法获取这些配置信息,但可通过查询 GV$OB_PARAMETERS 查看,并通过 alter system set 或启动配置文件设置。一般来说,不推荐修改这些配置项,保持默认值即可。

配置项 默认值 备注
_iut_enable true true为打开监控,false为关闭监控
_iut_max_entries 30000 表示能保存的索引表的最大个数
_iut_stat_collection_type SAMPLED 只有“ALL”和“SAMPLED”两种模式

备注:

  1. SAMPLED 模式下的采样率不开放配置。
  2. 配置项为租户级配置项,不同租户之间设置的值互不干扰。

视图说明

OceanBase 提供 DBA_INDEX_USAGE 视图,用来记录租户级索引统计数据。需要注意的是,当前视图中大部分字段为 预留字段,留作后续版本实现,本次发布生效的,有如下字段: OBJECT_ID,NAME,OWNER,TOTAL_ACCESS_COUNT,TOTAL_EXEC_COUNT,LASE_USED。

视图 DBA_INDEX_USAGE

列名 类型 含义
OBJECT_ID bigint(20) 索引表 ID
NAME varchar(128) 索引表名
OWNER varchar(128) 数据库名
TOTAL_ACCESS_COUNT bigint(20) 总共访问次数
TOTAL_EXEC_COUNT bigint(20) 总共执行次数
TOTAL_ROWS_RETURNED bigint(20) 总共返回的索引表行数
BUCKET_0_ACCESS_COUNT bigint(20) 索引表使用0次
BUCKET_1_ACCESS_COUNT bigint(20) 索引表引使用1次
BUCKET_2_10_ACCESS_COUNT bigint(20) 索引表使用2到10次
BUCKET_2_10_ROWS_RETURNED bigint(20) 索引表返回2到10行
BUCKET_11_100_ACCESS_COUNT bigint(20) 索引表访问11到100次
BUCKET_11_100_ROWS_RETURNED bigint(20) 索引表返回11到100行
BUCKET_101_1000_ACCESS_COUNT bigint(20) 索引表访问101到1000次
BUCKET_101_1000_ROWS_RETURNED bigint(20) 索引表返回101到1000行
BUCKET_1000_PLUS_ACCESS_COUNT bigint(20) 索引表被使用超过1000次
BUCKET_1000_PLUS_ROWS_RETURNED bigint(20) 索引表返回超过1000行
LASE_USED timestamp 索引表最后一次被使用的时间

查看监控数据

步骤一,建表和建索引

我们在新建表格和索引后插入一定量数据,然后执行 select 查询,并确认查询能走索引查询。这里可通过 explain 查看执行计划。

例如下面我新建了名为 t1 的表,表包含 c1,c2 两列数据,其中 idx1 是表的一个局部索引。

obclient [test]> explain select c1 from t1 where c1=1;
+-----------------------------------------------------------------------+
| Query Plan                                                            |
+-----------------------------------------------------------------------+
| ====================================================                  |
| |ID|OPERATOR        |NAME    |EST.ROWS|EST.TIME(us)|                  |
| ----------------------------------------------------                  |
| |0 |TABLE RANGE SCAN|t1(idx1)|2048    |74          |                  |
| ====================================================                  |
| Outputs & filters:                                                    |
| -------------------------------------                                 |
|   0 - output([t1.c1]), filter(nil), rowset=256                        |
|       access([t1.c1]), partitions(p0)                                 |
|       is_index_back=false, is_global_index=false,                     |
|       range_key([t1.c1], [t1.__pk_increment]), range(1,MIN ; 1,MAX),  |
|       range_cond([t1.c1 = 1])                                         |
+-----------------------------------------------------------------------+
12 rows in set (0.048 sec)

步骤二,查询索引使用

我们会在后台每隔 15 分钟把监控数据刷到磁盘里。因此,在等待 15 分钟后,索引使用记录会被刷新,此时我们查看 DBA_INDEX_USAGE 视图:

obclient [test]> select * from oceanbase.DBA_INDEX_USAGE;
Empty set (0.042 sec)

需要注意是的是,可能会出现查询为空的场景。这是由于集群启动索引监控为默认的采样模式,如上查询视图时并未查看到索引统计信息,但符合预期,采样模式下的数据可能会丢。如需准确信息,可以在当前租户下,设置监控信息收集模式为 _iut_stat_collection_type=ALL。如:

obclient [test]> alter system set _iut_stat_collection_type="ALL";
Query OK, 0 rows affected (0.056 sec)

备注:Oracle语法与MySQL的稍有差异,下面列举:

obclient [test]> alter system set "_iut_stat_collection_type"='ALL';
Query OK, 0 rows affected (0.064 sec)

重新执行select后,我们再过 15 分钟查询视图确认结果,如下结果的 TOTAL_ACCESS_COUNT 字段说明了 select 操作时,test 数据库下名为 idx1(__idx_500002_idx1)的索引被访问了 1 次,最后被访问的时间点为2023-11-17 16:01:54 。

obclient [test]> select * from oceanbase.DBA_INDEX_USAGE\G;
*************************** 1. row ***************************
                     OBJECT_ID: 500003
                          NAME: __idx_500002_idx1
                         OWNER: test
            TOTAL_ACCESS_COUNT: 1
              TOTAL_EXEC_COUNT: 1
           TOTAL_ROWS_RETURNED: 0
         BUCKET_0_ACCESS_COUNT: 0
         BUCKET_1_ACCESS_COUNT: 0
      BUCKET_2_10_ACCESS_COUNT: 0
     BUCKET_2_10_ROWS_RETURNED: 0
    BUCKET_11_100_ACCESS_COUNT: 0
   BUCKET_11_100_ROWS_RETURNED: 0
  BUCKET_101_1000_ACCESS_COUNT: 0
 BUCKET_101_1000_ROWS_RETURNED: 0
 BUCKET_1000_PLUS_ACCESS_COUNT: 0
BUCKET_1000_PLUS_ROWS_RETURNED: 0
                     LAST_USED: 2023-11-17 16:01:54.392561
1 row in set (0.049 sec)

清理监控数据

用户可能会担心反复删建索引造成的内存磁盘等资源占用不释放的问题。这点不需要担心,索引表被删除后,我们会在后台定期清理对应的监控数据记录,不需要用户手动干预,例如上面的例子中,我们删除了索引表:

obclient [test]> drop index idx1 on t1;
Query OK, 0 rows affected (0.679 sec)

在等待 15 分钟后,我们再次查看监控视图,记录已经被自动删除。

obclient [test]> select * from oceanbase.DBA_INDEX_USAGE\G;
Empty set (0.049 sec)

注意事项

  1. 由于内部使用 HashMap 保存索引表使用记录,并开放了隐藏配置项 _iut_max_entries 设置保存的索引表上限,该配置项设置过大可能会造成 HashMap 占租户内存较多,因此不建议设置超过 30000。
  2. 设置租户级配置项 _iut_stat_collection_type=ALL 模式可能会造成索引查询时一定的性能回退,需谨慎使用。
  3. 非用户租户的索引使用不在统计范围,视图仅展示用户租户数据。

FAQ

问:索引监控默认启动,会不会影响性能?

答:会,但默认(SAMPLED)模式下影响很小,几乎可以忽略。

问:采样模式下的数据是否准确 ?例如查询了 1 次,是否一定会被记录下来?

答:不一定,采样的目的是为了过滤部分数据,因此某次查询的记录可能会被丢弃。

问:备库的索引监控是只统计自己还是同步主库的?

答:统计是租户级的,备库可以查到主库同步的数据,但不能写入。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论