1.背景概述

近期应用升级上线过程中,存在删除业务表索引的变更操作,且因删除索引导致次日业务高峰时期,数据库响应缓慢的情况,经定位是缺失索引导致。与用户沟通,虽然变更中删除索引的需求很少,但也存在此类需求。

本文从数据库层面,旨在尽可能避免类似问题发生,制定删除索引的变更规范。

2.索引删除规范

若确认需要做索引删除,可以使用Oracle提供的两个功能特性协助判断删除索引是否会有隐患。

2.1 增加索引监控

将计划要删除的索引经过至少一个业务周期(具体业务确认业务周期为多久,注意要考虑到跑批场景)的监控,如果整个业务周期,该索引一直没有被使用过则可以考虑删除。

演示案例:

create table T as select * from dba_objects;

create index IDX_T_01 on T(object_id);

假设要删除的索引名称是IDX_T_01,使用下面语句开启该索引的监控。

alter index jingyu.IDX_T_01 monitoring usage;

索引是否使用到,会在具体业务schema下的v$object_usage视图中体现(具体观察USED这一列的值,如果是NO,说明自监控以来该索引从未使用过)

conn jingyu/jingyu

col index_name for a30

col table_name for a30

col START_MONITORING for a30

col END_MONITORING for a30

set lines 180

select * from v$object_usage;

INDEX_NAME TABLE_NAME MONITO USED START_MONITORING END_MONITORING

---------- ---------- ------ ------ ------------------------------ ------------------------------

IDX_T_01 T YES NO 07/22/2020 14:15:18

如果有人/应用执行过用到该索引的语句,比如:

select object_id from t where object_id = 3;

此时再观察USED这一列的值,已经变为yes,说明自监控以来该索引有被使用过,就不能被轻易删除:

INDEX_NAME TABLE_NAME MONITO USED START_MONITORING END_MONITORING

---------- ---------- ------ ------ ------------------------------ ------------------------------

IDX_T_01 T YES YES 07/22/2020 14:15:18

如果不再需要监控该索引,可以这样取消该索引的监控:

alter index jingyu.IDX_T_01 nomonitoring usage;

INDEX_NAME TABLE_NAME MONITO USED START_MONITORING END_MONITORING

---------- ---------- ------ ------ ------------------------------ ------------------------------

IDX_T_01 T NO NO 07/22/2020 14:30:30 07/22/2020 14:30:58

优点:简单,能有效监控整个业务周期内索引是否被使用到,如果没有被使用则可以放心删除。

缺点:只能判断是否被使用到,不能判断索引使用频率。

2.2 将删除索引先修改为不可见

将计划要删除的索引设置为不可见(invisible),然后经历至少一个业务周期(具体业务确认业务周期为多久,注意要考虑到跑批场景)的观察,确认没有影响,则可以考虑彻底删除。

设置索引IDX_T_01不可见:

alter index jingyu.IDX_T_01 invisible;

执行演示SQL发现已经是全表扫:

explain plan for select object_id from t where object_id = 3;

select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Plan hash value: 1601196873

--------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 11 | 143 | 283 (2)| 00:00:04 |

|* 1 | TABLE ACCESS FULL| T | 11 | 143 | 283 (2)| 00:00:04 |

--------------------------------------------------------------------------

恢复索引IDX_T_01可见:

alter index jingyu.IDX_T_01 visible;

执行演示SQL发现又恢复了索引访问,无需重建:

explain plan for select object_id from t where object_id = 3;

select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Plan hash value: 2968633466

-----------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-----------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 13 | 1 (0)| 00:00:01 |

|* 1 | INDEX RANGE SCAN| IDX_T_01 | 1 | 13 | 1 (0)| 00:00:01 |

-----------------------------------------------------------------------------

优点:因为invisible索引只是让优化器不可见,索引段中的数据依然存在且DML操作也会维护这些invisible的索引,所以回退(直接修改该索引为可见)非常方便。

缺点:如果删除索引是为了更快加载数据,那么设置索引invisible期间,并不会提升效率。另外应用会话如果有设置OPTIMIZER_USE_INVISIBLE_INDEXES=TRUE的参数,也会用到invisible索引,而这可能会造成误判,需要特别注意。

3.根本解决方案及建议

删除索引的情景一般是考虑到索引数量过多,从而导致索引维护成本和空间使用成本增加。一般原则是首先评估删除冗余索引,比如某张表同时有两个索引,索引A是c1列,索引B是c1,c2两列的复合索引,则一般可以选择删除索引A;但需要注意,如果索引B是c2和c1列的复合索引,就通常不可以删除索引A。其次,对其他计划删除的索引可以按照上文的规范来评估和操作。

oracle 清理索引空间,Oracle删除索引规范相关推荐

  1. mysql判断是否存在索引并删除_mysql判断索引存在时删除索引的方法_MySQL

    bitsCN.com mysql判断索引存在时删除索引的方法 mysql的drop index语句不支持if exists条件,在sql中先删除索引, 再创建索引,如果对于新建的数据库,库中没有该索引 ...

  2. oracle临时表空间自动清理,oracle清理临时表空间

    为了防止临时表空间无限制的增加,我采用隔一段时间就重建临时表空间的方法,为了方便,我保留两组语句,轮流执行即可, 假定现在临时表空间名称是temp,新建一个tempa表空间,删除temp表空间,方法如 ...

  3. oracle缩减临时表空间,oracle的临时表空间写满磁盘空间解决改问题的步骤

    oracle的临时表空间写满磁盘空间,解决改问题的具体步骤,以下的操作是用数据库的sys超级用户操作 刚开始打算把临时表空间的数据文件重新缩小就好了 执行: SQL> alter databas ...

  4. 生产上oracle扩展表空间,oracle基于裸设备(raw device)扩充表空间

    首先在oracle中查询表空间的使用情况,确认是哪个表空间不足. select df.tablespace_name "Tablespace",df.bytes/(1024*102 ...

  5. mysql无法删除索引_mysql – 无法删除索引

    以下create语句显示了我的一个MariaDB表的当前结构. CREATE TABLE `councilor` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, ...

  6. mysql判断是否存在索引并删除_mysql判断索引存在时删除索引的方法

    mysql的drop index语句不支持if exists条件,在sql中先删除索引,再创建索引,如果对于新建的数据库,库中没有该索引,就会报错,导致后面的sql不再执行. 因此需要使用存储过程来判 ...

  7. oracle清理undo空间,删除Oracle Undo表空间

    近期处理了一次删除.重建Undo表空间的事情,有些细节还是值得记下来备忘.事情的起因是工程师需要将分布在不同ASM磁盘组里的Oracle数据库文件,迁移到新建的ASM磁盘组,操作过程中,错误的删除了U ...

  8. oracle drop index pk,oracle – 执行唯一/主键 – 删除索引

    我想删除一个索引: DROP INDEX PK_CHARGES 但是我得到了这个错误 cannot drop index used for enforcement of unique/primary ...

  9. oracle清理表空间文件,如何自动删除表空间的文件?

    参考 http://asktom.oracle.com/pls/ask ... ITERIA:16212348050, begin dbms_pipe.pack_message( 'cmd' ); s ...

最新文章

  1. 10道海量数据处理的面试题
  2. python --那些你应该知道的知识点
  3. LightOJ 1088 - Points in Segments 二分
  4. Java程序员从笨鸟到菜鸟之(八)反射和代理机制
  5. 一些杂感杂想(一)谈谈加班、团队
  6. FIR调用DSP48E_05
  7. Android下实现GPS定位服务
  8. 置顶,博客中所有源码 github
  9. java精确除法运算-BigDecimal
  10. FPGA实现任意分频 为所欲为——教你什么才是真正的任意分频
  11. 3. PSR-3 --- 日志接口
  12. [转]python 正则匹配中文
  13. Redis 下载安装(Windows版本)
  14. Java线程池并发执行多个任务
  15. 趣味端午节,我的端午互动小平台
  16. python 爬取腾讯漫画
  17. 【错误记录】使用./make.sh ./make.sh install命令安装FastDFS时出错
  18. 如何将RAW格式的磁盘修改为NTFS?教给你三种操作方法
  19. GFP:新一代多业务传输技术(转)
  20. linux文件赋予用户权限,Linux 给用户赋予操作权限

热门文章

  1. 解决NVIDIA显卡 GPU显示器不可用的问题(亲测系列)
  2. RPA-机器人流程自动化
  3. 【Scratch】青少年蓝桥杯_每日一题_12.09_地球绕太阳转,月球绕地球转
  4. 对一阶电路的瞬态分析
  5. 骑行中的三个阶段,摇车效率最高
  6. 怀念在东莞理工学院的日子
  7. vue element-ui Tabs 标签页实现【更多】功能
  8. 进小区还用卡?你OUT了,手把手教你用最炫酷的方式过门禁
  9. elasticsearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解
  10. 微信--H5非微信内浏览器支付