设为首页 加入收藏

TOP

如何让ORACLE索引不可见(一)
2014-11-24 00:04:40 来源: 作者: 【 】 浏览:7
Tags:如何 ORACLE 索引 可见

我们经常在数据库上建索引或删除索引,由于索引对SQL的执行性能影响非常大,有可能变得很好,也有可能变得很差,在线下开发环境我们可以充分测试,对于创建或删除索引没什么问题。但是在线上环境,由于高并发的访问,如果我们删除了一个重要的大索引(GB以上),删除后才发现大量SQL性能变差,很快主机就LOAD飙升,系统无法运行了,由于索引已经删除,并且很大,要当场重建基本不可能,因为这个索引巨大,创建估计要几分钟甚至几个小时,况且这时主机已经基本没有响应,IO全部用光,只能把应用停了,等索引建好后再开始打开应用,等发生这样的事才会为自己的失误而后悔。那我们有没有办法让删除索引的风险降低呢,请看下文:

我们先创建一个表t1,在t1的table_name字段上新建一个索引idx_t1_table_name。

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 17 | 2 (50)|
| 1 | SORT AGGREGATE | | 1 | 17 | |
|* 2 | INDEX RANGE SCAN | IDX_T1_TABLE_NAME | 2 | 34 | 2 (50)|
--------------------------------------------------------------------------------

OK,从上面我们可以看到索引很正常。那现在假设我们不再需要这个索引了,因此想删除它,但又不知道会不会有本文开头所说的风险。如果可以删除前先把索引不可见,确认没问题后再删除,这样就没问题了,为此,Oracle11g推出新的功能,设置索引是否可见,示例如下:

SQL> alter index IDX_T1_TABLE_NAME invisible;

Index altered

SQL> explain plan for select count(*) from t1 where table_name=DUAL;

Explained

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 17 | 23 (22)|
| 1 | SORT AGGREGATE | | 1 | 17 | |
|* 2 | TABLE ACCESS FULL | T1 | 2 | 34 | 23 (22)|
-------------------------------------------------------------------------

这样索引就隐藏起来了,如果把索引隐藏后发现有性能问题,我们可以立即打开索引:
SQL> alter index IDX_T1_TABLE_NAME visible;

Index altered

SQL> explain plan for select count(*) from t1 where table_name=T1;

Explained

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3098159
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 17 | 1 (0)| 00:
| 1 | SORT AGGREGATE | | 1 | 17 | |
|* 2 | INDEX RANGE SCAN| IDX_T1_TABLE_NAME | 1 | 17 | 1 (0)| 00:
--------------------------------------------------------------------------------


以上是Oracle11g的处理方法,但是在Oracle9i或Oracle10g中索引没有invisible的功能,我们如何处理呢?
现在Oracle数据库一般都采用基于成本的计算方法来生成执行计划,只要索引的成本更低,ORACLE就会选择使用索引,OK,那我们只要告诉ORACLE使用这个索引成本很高,它就不会使用这个索引,这样就达到了暂时让索引不可用的效果。相信很多人都知道ORACLE提供了dbms_stats包来管理对像的统计信息,通过dbms_stats.set_index_stats函数我们可以强制设置统计信息,现在我们只要把索引的成本设置成非常大即可,如下所示:

--查看IDX_T1_TABLE_NAME的基本统计信息
SQL> select a.owner,a.index_name,a.blevel,a.leaf_blocks,a.num_rows from all_indexes a where owner=YZS and index_name=IDX_T1_TABLE_NAME;

OWN

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Oracle创建索引策略 下一篇在Oracle中列出指定数据表的全部..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: