定义:虚拟索引(virtual index) 是指没有创建对应的物理段的索引。

虚拟索引的目的:是在不损耗主机CPU,IO,磁盘空间去实际创建索引的情况下,来判断一个索引是否能够对SQL优化起到作用。列如我们在优化一条SQL语句的时候,通常会查看需要优化的语句的执行计划,在考虑是否需要在表的某列上建立索引时就可以用到虚拟索引。虚拟索引建立的时候因为其没有消耗主机的相关资源,因此可以在相当快的时间内建立完成。

下面我们来看一下试验:

首先建立两张测试表

create table bigtab as select rownum as id,a.* from sys.all_objects a;

create table smalltab as select rownum as id,a.* from  a;

create table smalltab as select rownum as id,a.* from sys.all_tables a;

多次运行以下语句,以插入多一些测试数据:

insert into bigtab select ronum as id,a.* from sys.all_objects a;

insert into smalltab select rownum as id,a.* from sys.all_tables a;

查看需要执行语句的执行计划:

SQL> explain plan for select count(*) from bigtab a,smalltab b where a.object_name=b.table_name;

Explained.

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3089226980 --------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 40 | 518 (1)| 00:00:07 |
| 1 | SORT AGGREGATE | | 1 | 40 | | |
|* 2 | HASH JOIN | | 99838 | 3899K| 518 (1)| 00:00:07 |
| 3 | TABLE ACCESS FULL| SMALLTAB | 15311 | 299K| 172 (0)| 00:00:03 |
| 4 | TABLE ACCESS FULL| BIGTAB | 85284 | 1665K| 345 (1)| 00:00:05 |
-------------------------------------------------------------------------------- PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME") 16 rows selected.

下面我们在两个表上创建两个虚拟索引,分别在object_name和table_name列上,看看优化器是否会使用这两个索引,以及优化器的成本会如何变化。

SQL> show parameter _use_nosegment
SQL> alter session set "_use_nosegment_indexes"=true; Session altered. SQL> show parameter _use_nosegment NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_use_nosegment_indexes boolean TRUE
SQL> create index big_ind on bigtab(object_name) nosegment; Index created. SQL> create index small_ind on smalltab(table_name) nosegment;

create index语句的NOSEGMENT选项表明这个索引是“虚拟的”-----就是没有与之相关联的实际索引段。如果优化器认为这个索引有用,参数_use_nosegment_indexes将指示数据库可以在执行计划中使用这些索引。下面我们来看看如果真的创建这些索引,它们是否值得使用:

SQL> explain plan for select count(*) from bigtab a,smalltab b where a.object_name=b.table_name;

Explained.

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1254475829 ------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 40 | 19 (6)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 40 | | |
|* 2 | HASH JOIN | | 99838 | 3899K| 19 (6)| 00:00:01 |
| 3 | INDEX FAST FULL SCAN| SMALL_IND | 15311 | 299K| 9 (0)| 00:00:01 |
| 4 | INDEX FAST FULL SCAN| BIG_IND | 85284 | 1665K| 9 (0)| 00:00:01 |
------------------------------------------------------------------------------------ PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME") 16 rows selected.

执行计划显示,这两个索引确实被认为有用,优化器估算的成本也下降到19了。所以如果需要优化语句可以建议创建这些索引。

在优化SQL语句中使用虚拟索引的更多相关文章

  1. 应用索引技术优化SQL 语句(转)

    原文出处 一.前言 很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句.这类SQL语句性能不好的首要原因是缺乏高效的索引.没有索引除了导致语句本身运行速度慢外,更是导致 ...

  2. MySQL查询不使用索引汇总 + 如何优化sql语句

    不使用索引原文 : http://itlab.idcquan.com/linux/MYSQL/918330.html MySQL查询不使用索引汇总 众所周知,增加索引是提高查询速度的有效途径,但是很多 ...

  3. 三,mysql优化--sql语句优化之索引一

    1,需求:如何在一个项目中,找到慢查询的select,mysql数据库支持把慢查询语句,记录到日志中.供程序员分析.(默认不启用此功能,需要手动启用) 修改my.cnf文件(有些地方是my.ini) ...

  4. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  5. SQL Server数据库性能优化(一)之 优化SQL 语句

    最近工作上基本没什么需求(好吧 不是最近是好久了,所以随便看看基础的东西来填补自己的空白) 原文出自:http://www.blogjava.net/allen-zhe/archive/2010/07 ...

  6. mysql优化SQL语句的一般步骤及常用方法

    一.优化SQL语句的一般步骤 1. 通过show status命令了解各种SQL的执行频率 mysqladmin extended-status 或: show [session|global]sta ...

  7. SQL点滴35—SQL语句中的exists

    原文:SQL点滴35-SQL语句中的exists 比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers c WHE ...

  8. mysql优化sql语句

    mysql优化sql语句   常见误区   www.2cto.com   误区1:   count(1)和count(primary_key) 优于 count(*)   很多人为了统计记录条数,就使 ...

  9. MySql(五)SQL优化-优化SQL语句的一般步骤

    MySql(五)SQL优化-优化SQL语句的一般步骤 一.优化SQL语句的一般步骤 1.1 通过show status命令了解各种SQL的执行频率 1.2 定位执行效率较低的SQL语句 1.3 通过e ...

随机推荐

  1. ASPxGridView-如何在客户端缓存数据

    有时候我们可以直接从后台生成一些值缓存到客户端,在用到的时候无需在进行callback进行取值,减少和服务器的交互.下面的例子缓存列"title_id"和"title&q ...

  2. MYSQL—加写锁,加读锁,解锁

    链接地址:http://blog.sina.com.cn/s/blog_7fa2bcf50101j1lu.html 表级锁: 加写锁:          lock   tables   table_n ...

  3. BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草( dp )

    -------------------------------------------------------------------- #include<cstdio> #include ...

  4. JavaEE学习之类加载器

    类装载子系统 在JAVA虚拟机中,负责查找并装载类型的那部分被称为类装载子系统. JAVA虚拟机有两种类装载器:启动类装载器和用户自定义类装载器.前者是JAVA虚拟机实现的一部分,后者则是Java程序 ...

  5. eclipse maven SLF4J: Failed to load class org.slf4j.impl.StaticLoggerBinder

    现象:运行eclipse maven build,console 有红色日志如下: SLF4J: Failed to load class "org.slf4j.impl.StaticLog ...

  6. PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?

    首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...

  7. HTML+CSS笔记 CSS中级 一些小技巧

    水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...

  8. IOS 页面之间的传值(主讲delegate)

    IOS的Delegate,通俗一点说就是页面之间的传值. 总结一下现在知道的IOS页面之间传值的方式有三种 1.使用NSNotification发送通知的传值 主要是通过NSNotificationC ...

  9. Windows10笔记本双显卡导致的启动黑屏解决办法之一

    参考链接:http://www.zhihu.com/question/33662311 大概就是关掉ulps. ulps,显卡的多核心超低功率状态,节能用的,AMD出的双显卡的一种节能方案.不过,与某 ...

  10. Qt官方开发环境生成的exe发布方式--使用windeployqt(windeployqt是单独的程序,放在低版本qt4目录下也可以运行的)

    Qt 官方开发环境使用的动态链接库方式,在发布生成的exe程序时,需要复制一大堆 dll,如果自己去复制dll,很可能丢三落四,导致exe在别的电脑里无法正常运行.因此 Qt 官方开发环境里自带了一个 ...