老板交给的一个任务,搜了一下资料,觉得还是总结一下比较好。假如以后用到了呢?围绕两个主题:一是视图上能够建索引,二是在创建索引时是否可以使用DESC关键字。
一、能否在视图上创建索引
在oracle中执行如下的语句,会报“视图不适用于此处”的错误
create view test_car
as
select license
from cars;
create index index_vew_car on test_car(license);
那当需要对视图进行大量查询,而查询效率较低时,如何处理呢?有以下几种方法:
Oracle 中有物化视图可以建立索引,SQLServer 中索引视图可以建立索引,Oracle 中基于函数的索引也可以解决这个问题。
1、物化视图
Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据,也可以称为快照。
物化视图可以用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL语句的正确性和有效性;物化视图需要占用存储空间;当基表发生变化时,物化视图也应当刷新。
物化视图可以查询表,视图和其它的物化视图。
通常情况下,物化视图被称为主表(在复制期间)或明细表(在数据仓库中)。
对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的。如果你想修改本地副本,必须用高级复制的功能。当你想从一个表或视图中抽取数据时,你可以用从物化视图中抽取。
对于数据仓库,创建的物化视图通常情况下是聚合视图,单一表聚合视图和连接视图。
在复制环境下,创建的物化视图通常情况下主键,rowid,和子查询视图。
物化视图由于是物理真实存在的,故可以创建索引。
如何创建物化视图及使用示例见如下第一条参考。
参考:http://blog.csdn.net/tianlesoftware/article/details/4713553
对比普通视图
普通视图不存储物理信息,仅仅是一个sql语句。所以不能在其上创建索引。
物化视图是物理真实存在的,可以创建索引。
参考:普通视图和物化视图区别
2、SQLServer 中的索引视图
SQLServer 中可以创建索引视图,类似于物化视图的概念。
SQLServer 创建索引视图的几个注意事项见以下参考链接。
参考:如何在视图上创建索引
SQL Server 2008 创建索引视图(物化视图) 的一点总结
3、Oracle 中基于函数的索引
概念:在DML操作时如果经常使用某个表达式作为条件,那么可以建立基于该函数的索引。在创建此类索引时,Oracle首先对包含索引列的函数或表达式进行求值,然后对这些值进行排序,最后再存储到索引中。基于函数的索引可以是普通的B树索引,也可以是位图索引。
动机:比如执行如下一条SQL语句:select * from emp where upper(ename) = 'KING',即使在ename上建立了索引,还是会全表扫描emp表,将里面的ename字段改成大写跟常量KING进行比较。如果我们建立一个基于函数的索引,比如:create index emp_upper_idx on emp(upper(ename)); 这个时候,我们只需要按区间扫描小部分数据,然后获取rowid取访问表中的数据,这个速度是比较快的。
基于函数的索引,类似于普通的索引,只是普通的索引是建立在列上,而它是建立在函数上。当然这回对插入数据有一定影响,因为需要通过函数计算一下,然后生成索引。但是插入数据一般都是少量插入,而查询数据一般数据量比较大。为了优化查询速度,稍微降低点插入速度是可以承担的。
一个例子
谈到任何对列的操作都可能导致全表扫描,例如:
select * from emp where substr(ename,1,2)=’SM’;但是这种查询在客服系统又经常使用,我们可以创建一个带有substr函数的基于Oracle函数索引,
create index emp_ename_substr on eemp ( substr(ename,1,2) );这样在执行上面的查询语句时,这个基于函数的索引将排上用场,执行计划将是(INDEX RANGE SCAN)。
上面的例子中,我们创建了基于函数的索引,但是如果执行下面的查询:
select * from emp where substr(ename,1,1)=’S’得到的执行计划将还是(TABLE ACCESS FULL),因为只有当数据列能够等式匹配时,基于函数的索引才能生效,这样对于这种索引的计划和维护的要求都很高。请注意,向表中添加索引是非常危险的操作,因为这将导致许多查询执行计划的变更。然而,如果我们使用基于函数的索引就不会产生这样的问题,因为Oracle只有在查询使用了匹配的内置函数时才会使用这种类型的索引。( 我的理解是,创建普通的索引时会导致查询执行计划的变更;而创建函数索引,只有当查询条件匹配时,执行计划才会考虑这个索引。)
参考:《Oracle 数据库应用与开发》
二、创建索引时能否用 DESC
Oracle 创建索引的语法如下:
create [ unique | bitmap ] index [ schema. ] < index_name >
on [ schema. ] < table_name >
(< column_name > | < expression > ASC | DESC,
< column_name > | < expression > ASC | DESC, ...)
[ tablespace < tablespace_name >]
[ storage ( < storage_settings > ) ]
[ logging | nologging ]
[ nosort | reverse ]
[ partition | global partition <partition_setting> ]
其中ASC和DESC表示创建的索引为升序、降序排列。创建索引时可以指定多个字段或多个表达式,之间用逗号隔开。
如:
create table cars
(
license int,
owner varchar(8),
model varchar(8)
);
create index idx_carlcs on cars(license DESC);
参考:《Oracle 数据库应用与开发》