Oracle之虚拟索引
一、引言
DBA在日常维护管理数据库进行低性能SQL分析时,有时候需要通过创建索引对SQL进行优化,但有些时候我们创建的索引是否能用到?这个只能创建以后才能看出效果,但是在实际工作中,特别是对大表创建索引对系统性能有很大影响,因此我们不得不避开业务高峰时段,但是有没有一种办法创建索引而不影响性能呢?有,那就是虚拟索引。
虚拟索引不是物理存在的,它并不会创建实际的索引段,只是在数据字典中加了一个索引的记录,使得优化器能够意识到一个索引的存在,从而判断是否使用该索引作为访问路径。作用仅仅是为了DBA作SQL优化时使用,DBA根据虚拟索引的优化效果决定是否创建物理索引。
二、虚拟索引类型
虚拟索引支持B-TREE索引和BIT位图索引,在CBO模式下ORACLE优化器会考虑虚拟索引,但是在RBO模式下需要添加hint才行。
三、虚拟索引创建实例
SQL> drop table t purge;
表已删除。
SQL> create table t as select * from dba_objects;
表已创建。
--创建虚拟索引,首先要将_use_nosegment_indexes的隐含参数设置为true
SQL> alter session set "_use_nosegment_indexes"=true;
会话已更改。
--虚拟索引的创建语法比较简单,实际上就是普通索引语法后面加一个nosegment关键字
SQL> create index ix_t_id on t(object_id) nosegment;
索引已创建。
SQL> explain plan for select * from t where object_id=;
已解释。
SQL> set linesize
SQL> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value:
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
| | TABLE ACCESS BY INDEX ROWID| T | | | ()| :: |
|* | INDEX RANGE SCAN | IX_T_ID | | | ()| :: |
--------------------------------------------------------------------------------------- Predicate Information (identified by operation id): PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - access("OBJECT_ID"=) Note
-----
- dynamic sampling used for this statement (level=) 已选择18行。 SQL> set autotrace traceonly
SQL> select * from t where object_id=; 未选定行 执行计划
----------------------------------------------------------
Plan hash value: ---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
| | TABLE ACCESS BY INDEX ROWID| T | | | ()| :: |
|* | INDEX RANGE SCAN | IX_T_ID | | | ()| :: |
--------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- - access("OBJECT_ID"=) Note
-----
- dynamic sampling used for this statement (level=) 统计信息
----------------------------------------------------------
recursive calls
db block gets
consistent gets
physical reads
redo size
bytes sent via SQL*Net to client
bytes received via SQL*Net from client
SQL*Net roundtrips to/from client
sorts (memory)
sorts (disk)
rows processed SQL> set autotrace off
--以下看的是真实执行计划,显然是用不到索引。
SQL> alter session set statistics_level=all; 会话已更改。 SQL> select * from t where object_id=; 未选定行 SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 2qhwh0nzrzx2r, child number
-------------------------------------
select * from t where object_id= Plan hash value: ------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | |::00.01 | |
|* | TABLE ACCESS FULL| T | | | |::00.01 | | PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id):
--------------------------------------------------- - filter("OBJECT_ID"=) Note
-----
- dynamic sampling used for this statement (level=) 已选择22行。
--从数据字段中是无法找到这个索引的。
SQL> select index_name,status from user_indexes where table_name='T'; 未选定行
四、虚拟索引的特点
4.1、虚拟索引无法执行alter index选项
SQL> alter index IX_T_ID rebuild;
alter index IX_T_ID rebuild
*
第 1 行出现错误:
ORA-08114: 无法变更假索引
4.2、使用回收站特性的时候,虚拟索引必须显示drop,才能创建同名的索引。
SQL> create index ind_status on t(status); 索引已创建。
SQL> drop table t; 表已删除。 SQL> flashback table t to before drop; 闪回完成。 SQL> select table_name,index_name,status from user_indexes where table_name='T'; TABLE_NAME INDEX_NAME STATUS
------------------------------ ------------------------------ --------
T BIN$7jAFlUG6b1zgQAB/AQAPyw==$0 VALID SQL> create index ind_object_id on t(object_id); 索引已创建。 SQL> create index inds_status on t(status);
create index inds_status on t(status)
*
第 1 行出现错误:
ORA-01408: 此列列表已索引
4.3、不能创建和虚拟索引同名的实际索引;
4.4、可以创建和虚拟索引包含相同列但不同名的实际索引;
4.5、虚拟索引分析并且有效,但是数据字典里查不到结果。
Oracle之虚拟索引的更多相关文章
- 【索引】Oracle之不可见索引和虚拟索引的比对
[索引]Oracle之不可见索引和虚拟索引的比对 Oracle之不可见索引 :http://blog.itpub.net/26736162/viewspace-2124044/ Oracle之虚 ...
- ORACLE虚拟索引(Virtual Index)
ORACLE虚拟索引(Virtual Index) 虚拟索引概念 虚拟索引(Virtual Indexes)是一个定义在数据字典中的假索引(fake index),它没有相关的索引段.虚拟索引的目 ...
- Oracle性能调优之虚拟索引用法简介
本博客记录一下Oracle虚拟索引的用法,虚拟索引是定义在数据字典中的伪索引,可以说是伪列,没有修改的索引字段的.虚拟索引的目的模拟索引,不会增加存储空间的使用,有了虚拟索引,开发者使用执行计划的时候 ...
- Oracle虚拟索引,大表或生产环境下预估索引效果的好东西
在数据库优化过程中,索引的重要性是不言而喻的,但是在我们进行性能调整过程中, 一个索引是否能够被使用到,在索引创建之前是存在不确定性的. 而创建索引又是一个代价很高的操作,尤其是数据量很大的情况下,在 ...
- Oracle 11g 虚拟列 Virtual Column介绍
Oracle 11G 虚拟列 Virtual Column Oracle 11G 在表中引入了虚拟列,虚拟列是一个表达式,在运行时计算,不存储在数据库中,不能更新虚拟列的值. 定义一个虚拟列的语法: ...
- ORACLE不可见索引(Invisible Indexes)
不可见索引概念 不可见索引(Invisible Index)是ORACLE 11g引入的新特性.不可见索引是会被优化器忽略的不可见索引,除非在会话或系统级别上将OPTIMIZER_USE_INVISI ...
- ORACLE表、索引和分区详解
ORACLE表.索引和分区 一.数据库表 每种类型的表都有不同的特性,分别应用与不同的领域 堆组织表 聚簇表(共三种) 索引组织表 嵌套表 临时表 外部表和对象表 1.行迁移 建表过程中可以指定以下两 ...
- Oracle序列和索引
序列和索引 一.序列 1.序列的概念: 序列(Sequence)是用来生成连续的整数数据的对象.它常常用来作为主键的增长列,可以升序,也可以降序. 2.创建序列: 语法:创建序列 ...
- Oracle中的索引详解
Oracle中的索引概述 索引与表一样,也属于段(segment)的一种.里面存放了用户的数据,跟表一样需要占用磁盘空间.索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是 ...
随机推荐
- Android 百度地图SDK 定位
引用locSDK_6.1.3.jar,切记添加相应的so文件. 1.定位初始化,需要使用getApplicationContext() mLocClient = new LocationClient( ...
- 第三篇 Integration Services:增量加载-Adding Rows
本篇文章是Integration Services系列的第三篇,详细内容请参考原文. 增量加载是什么增量加载仅加载与先前加载差异的.差异包括:->新增的行->更新的行->删除的行通过 ...
- 利用WebService发布图片文件
服务器端: 1.新建一个Asp.net空网站RGImageServer. 2.新建一个WebService项目ImageService,项目新增文件ImageService.asmx,添加方法GetT ...
- IIS应用程序池添加ASP.NET v4.0
可能在安装.NET Framewrok 4.0之前,IIS就已经装好了,结果在IIS的应用程序池中只有.NET 2.0的Classic .NET AppPool和DefaultAppPool.在使用v ...
- 高级选择器querySelector和querySelectorAll
Javascript新提供的querySelector和querySelectorAll方法,是仿照CSS选择器功能编写的 querySelector 功能:该方法返回满足条件的单个元素.按照深度优先 ...
- 重复点击主界面(TabBar)按钮刷新界面--点击状态栏回到顶部
1.监听按钮点击 2.判断是否是点击的同一个按钮(记录上次点击的按钮) 3.当重复点击相同按钮时,需要获取当前按钮对应控制器刷新界面 3.1 判断是否重复点击按钮,代码写在哪里? ...
- sql server常见服务
根据您决定安装的组件,SQL Server 安装程序将安装以下服务: SQL Server Database Services - 用于 SQL Server 关系数据库引擎的服务. 可执行文件为 & ...
- 20145207 《Java程序设计》第8周学习总结
前言: 这两天电路焊小车,有意思归有意思,确实挺忙的.博客到现在才写.执勤看的东西忘得好快呀,莫名的记不住.不说废话了,开始. 教材学习内容总结: 一.NIO和NIO2 1.NIO的定义 InputS ...
- [原创]java WEB学习笔记50:文件上传案例
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Java基础(9):Java生成随机数一定范围内的数的一个典型例子
题目:编写一个JAVA程序,创建指定长度的 int 型数组,并生成 100 以内随机数为数组中的每个元素赋值,然后输出数组 note: 通过 (int)(Math.random() * 100) 生成 ...