1.oracle优化器
优化目标分为4种:
choose (选择性)
rule (基于规则)
first rows(第一行)
all rows(所有行)
Description:描述sql的执行计划
Object owner:对象模式
Object name:对象名
Cost:花费(的时间)
Cardinality:基数,约等于行数
Bytes:空间(访问的存储空间)

2.table的访问方式
2.1全表扫描(table access full)
全表扫描就是顺序地访问表中每条记录。
oracle采用一次读入多个数据块(database block)的方式优化全表扫描。
举例:
select * from emp;

2.2通过rowid访问表(table access by user/index rowid)
可以采用基于rowid的访问方式情况,提高访问表的效率。
rowid包含了表中记录的物理位置信息。
oracle采用索引(index)实现了数据和存放数据的物理位置(rowid)之间的联系。
通常索引提供了快速访问rowid的方法,因此那些基于索引列的查询就可以得到性能上的提高。
举例:
select rowid,emp.* from emp where rowid='AAAR3sAAEAAAACXAAA';
select * from emp where empno=7788;

--清除数据库内存缓冲区
alter system flush buffer_cache;

索引(index)
1.索引定义
索引是一种与表相关联的可选结构,有时可以提高数据访问速度。
通过在表中的一个或多个列上创建索引,
通常情况下能够(快速地)从随机分布的表行中检索一小部分行。
索引是减少磁盘 i/o 的许多手段之一。
如果一个表没有索引,数据库必须执行全表扫描来查找值。
测试:
select * from all_objects;
create table tab_all_objects as select * from all_objects;
select * from tab_all_objects;
35s-->26s
select * from tab_all_objects where object_name='STUDENT';
0.531s-->0.015s
create index idx_object_name on tab_all_objects (object_name);
练习:
select owner,view_name,text_length,editioning_view,read_only from all_views;
create table tab_all_views as select owner,view_name,text_length,editioning_view,read_only from all_views;
select * from tab_all_views;
0.515s-->0.498s
select * from tab_all_views where view_name='VIEW_EMP';
0.499s-->0.062s
create index idx_view_name on tab_all_views (view_name);

select * from emp,dept where emp.deptno=dept.deptno;
0.109s-->0.031s
create index idx_emp_deptno on emp (deptno);
通常,在下列情况下可以考虑在某列上创建索引:
某个列经常被作为查询条件,并且查询结果只返回了表中的一小部分行。5% >20%
列或列集上存在引用完整性约束(是外键列)。

二、语法
2.1 创建索引
create [unique | bitmap] index 索引名 on 表名 { ([<expr>] <col> [asc | desc] [, …])
举例:
create index idx_emp_deptno on emp (deptno); 普通索引
create unique index idx_emp_ename on emp (ename); 唯一索引
create index idx_emp_job_sal on emp (job,sal); 复合索引
create index idx_emp_sal on emp (sal*12); 函数索引

select * from emp where deptno=20;
select * from emp where ename='FORD';
select * from emp where job='MANAGER' and sal>=2500;
select * from emp where sal*12>=20000;

select * from tab_all_objects where object_id=74975;
create index idx_object_id on tab_all_objects (object_id);

--select * from tab_all_objects where object_type='SYNONYM';
--create index idx_object_type on tab_all_objects (object_type);

2.2 修改索引
alter index <ind> {enable | disable};
alter index <ind> rename to <new>;
举例:
alter index IDX_EMP_SAL disable;
alter index idx_emp_deptno disable;
alter index IDX_EMP_SAL rename to IDX_EMP_SAL1;
alter index IDX_EMP_SAL1 rename to IDX_EMP_SAL;

2.3 删除索引
drop index <ind>;
举例:
--drop index IDX_EMP_SAL;

2.4 分析索引
analyze index <ind> validate structure online|offline;
举例:
analyze index IDX_EMP_SAL validate structure online;

2.5 重建索引
alter index <ind> rebuild
举例:
alter index IDX_EMP_SAL rebuild;

--授权
connect sys/123 as sysdba;
grant create any index,drop any index,alter any index to scott;

三、索引特征
索引是一种模式对象,它在逻辑上和物理上都与其相关联表对象的数据保持独立。
因此,可以删除或创建索引而不会实际影响相关的表。
如果删除一个索引,应用程序将仍然可以工作。不过,访问之前通过索引访问的数据可能会变慢。
索引的存在与否,不需要改变任何sql语句的写法。
索引是到单一行数据的快速访问路径。它只影响执行的速度。
对于一个已被索引的给定的数据值,索引直接指向包含该值的行的位置。
在表上存在过多的索引,会降低dml性能,因为数据库还必须更新索引。
主键和唯一键会自动生成索引,但需要手动在外键上创建索引。
create index ind_emp_deptno on emp_test (deptno);
select * from emp,dept where emp.deptno=dept.deptno;

四、复合索引
复合索引,也称为连接索引,是在某个表中的多个列上的索引。
复合索引中的列应该以在检索数据的查询中最有意义的顺序出现,但在表中不必是相邻的。
若 where 子句引用了复合索引中的所有列或前导列,
复合索引可以加快 select 语句的数据检索速度。
所以,在定义中所使用的列顺序很重要。一般地,最常被访问的列放在前面。

五、唯一索引和非唯一索引
索引可以是唯一的或非唯一的。
唯一索引保证在表的键列或键列集上没有具有重复的值的行。
在一个唯一索引中,对每个数据值都存在一个 rowid。叶块中的数据仅根据键排序。
非唯一索引允许在索引的列或列集中有重复的值。
对于非唯一索引,rowid 被包含在键中且已排序,
因此非唯一索引按索引键和 rowid (升序) 进行排序。

六、索引类型
索引类型分为:b-树索引、位图索引、基于函数的索引

6.1 b-树索引
这是索引的标准类型。对于主键和高选择性索引非常适合。
平衡树,简称b-树,是最常见的数据库索引类型。
一个 b-树索引是被划分为多个范围的已排序的值列表。
通过将键与一行或行范围关联起来 ,b-树可以对多种类型的查询提供优秀的检索性能,
包括精确匹配和范围搜索等。

二分查找算法是在有序数组中用到的较为频繁的一种算法。
在未接触二分查找算法时,
最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).
但二分查找算法则更优,因为其查找时间为O(lgn)。
比如数组{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},查找元素6,
用二分查找的算法执行的话,其顺序为:
1.找中位数,用中位数和6比较,如果中位数比6大,则在中位数左侧数组中查找;如果中位数比6小,则在中位数右侧数组中查找;
2.循环步骤1,直到等于要查找的值,并返回;或者找不到要查找的值,则返回空。

select index_type,count(1) from dba_indexes where 1=1 group by index_type order by count(1) desc;
1 NORMAL 3681
2 LOB 901 BLOB、CLOB列产生的,非单独索引(view PLAN_TABLE$;)
3 IOT - TOP 158 索引组织表的主键索引(view SQLLOG$;)
4 FUNCTION-BASED NORMAL 40 基于函数的索引(view DBFS$_MOUNTS;)
5 BITMAP 16 位图索引
6 CLUSTER 10
7 FUNCTION-BASED DOMAIN 4
8 DOMAIN 1

create bitmap index SH.SALES_PROD_BIX on SH.SALES (PROD_ID);

6.2 位图索引
在位图索引中,索引条目使用位图来指向多个行。
create index idx_emp_deptno on emp (deptno);
drop index idx_emp_deptno;
create bitmap index idx_emp_deptno on emp (deptno);

6.3 基于函数的索引
这种类型的索引包括经过一个函数(如upper函数)转换过的列,或包括在表达式中的列。
create index idx_emp_ename_lower on emp (lower(ename));

七、索引扫描
在索引扫描中,数据库使用语句指定的索引列,通过遍历索引来检索行。
数据库扫描索引,将使用n个i/o就能找到其要查找的值,其中 n 即是b-树索引的高度。
这是数据库索引背后的基本原理。
如果 sql 语句仅访问被索引的列,那么数据库只需直接从索引中读取值,而不用读取表。
如果该语句同时还需要访问除索引列之外的列,那么数据库会使用 rowid 来查找表中的行。
通常,为检索表数据,数据库以交替方式先读取索引块,然后读取相应的表块。

7.1.完全索引扫描 INDEX FULL SCAN
select emp.* from emp,dept where emp.deptno=dept.deptno;
在完全索引扫描中,数据库顺序读取整个索引。
如果在 sql 语句中的谓词 (where 子句) 引用了一个索引列,
或者在某些情况下未不指定任何谓词,此时可能使用完全索引扫描。
完全扫描可以消除排序,因为数据本身就是基于索引键排过序的。

7.2快速完全索引扫描 INDEX FAST FULL SCAN
select view_name from tab_all_views;
--all rows
快速完全索引扫描是一种完全索引扫描,数据库并不按特定的顺序读取索引块。
数据库仅访问索引本身中的数据,而无需访问表。
当索引包含了查询所需的所有列,且索引键中至少一列具有 not null 约束时,快速完全索引扫描可以替代全表扫描。

7.3 索引范围扫描 INDEX RANGE SCAN
create index idx_emp_deptno on emp (deptno);
select * from emp where deptno=10;
索引范围扫描是对索引的有序扫描,具有以下特点:
在条件中指定了一个或多个索引前导列。
条件指定一个或多个表达式和逻辑 (布尔) 运算符的组合,并返回一个值( true、 false,或unknown)。
一个索引键可能对应0个、1个或更多个值。
通常,数据库使用索引范围扫描来访问选择性的数据。
选择性是查询所选择的数据占总行数的百分比, 0 意味着没有任何行,1 表示所有行。
选择性与一个(或多个)查询谓词相关,比如where last_name like 'a%'。
值越接近 0的谓词越具有选择性,相反,越接近1的谓词则越不具有选择性。

7.4 唯一索引扫描 INDEX UNIQUE SCAN
select * from emp where empno=7788;

相对于索引范围扫描,唯一索引扫描必须是 有0个 或 1个 rowid 与索引键相关联。
当一个谓词使用相等运算符引用了唯一索引键的所有列时,数据库将执行唯一扫描。
只要找到了第一个记录,唯一索引扫描就停止处理,因为不可能有第二个记录满足条件。

7.5 索引跳跃扫描 INDEX SKIP SCAN
如果在复合索引前导键列中有少量不同值,而在非前导键列中有大量不同值,此时使用跳跃扫描是有益的。
--建表
create table stu
(
sex varchar2(1) not null,
sid number(8)
);
--建复合索引
create index idx_stu_sexandsid on stu(sex,sid);
--插数据
declare
begin
for i in 1..1000 loop
insert into stu values('M',i);
end loop;
for i in 1001..2000 loop
insert into stu values('F',i);
end loop;
end;
--分析表
analyze table stu compute statistics;
--分析SQL执行计划
select * from stu where sid=100;
索引跳跃扫描使用复合索引的逻辑子索引。
数据库“跳跃地”通过单个索引,好像它在多个单独的索引中搜索一样。
当在查询谓词中未指定组合索引的前导列时,数据库可能选择索引跳跃扫描。

索引是根据指定的数据库表列建立起来的顺序。
它提供了快速访问数据的途径,并且可监督表的数据,使其索引所指向的列中的数据不重复。
分为单列索引和组合索引。
主键、唯一键系统自动创建索引,外键系统不会自动创建索引。
外键不创建索引时将导致父子表连接查询时出现子表的全表扫描。

伪列rowid
1.定义:
oracle数据库的表中的每一行数据都有一个唯一的标识符,或者称为rowid,
在oracle内部通常就是使用它来访问数据的。
rowid需要 10个字节的存储空间,并用18个字符来显示。
该值表明了该行在oracle数据库中的物理具体位置。
可以在一个查询中使用rowid来表明查询结果中包含该值。
select rowid,emp.* from emp where rowid='AAAR3sAAEAAAACXAAA';
73196

2.存储
保存rowid需要10个字节或者是80个位二进制位。
这80个二进制位分别是:
1. 数据对象编号,表明此行所属的数据库对象的编号,每个数据对象在数据库建立的时候
都被唯一分配一个编号,并且此编号唯一。数据对象编号占用大约32位。
2. 对应文件编号,表明该行所在文件的编号,表空间的每一个文件标号都是唯一的。
文件编号所占用的位置是10位。
3. 块编号,表明改行所在文件的块的位置块编号需要22位。
4. 行编号,表明该行在行目录中的具体位置行编号需要16位。
这样加起来就是80位。

3.显示
Oracle的物理扩展ROWID有18位,每位采用64位编码,分别用A~Z、a~z、0~9、+、/共64个字符表示。
A表示0,B表示1,……Z表示25,a表示26,……z表示51,0表示52,……,9表示61,+表示62,/表示63。
64位编码表示的ROWID有18位,其中:
数据对象编号占6位;
文件编号占3位;
块编号占6位;
行编号占3位。
select log(2,64),log(2,64)*18 from dual;

4.举例:
select rowid,empno,ename from emp;
将会得到结果:
AAAR3sAAEAAAACXAAA
说明:
AAAR3s是数据库对象编号,AAE是文件标号,AAAACX是块编号,最后三位AAA(SMITH)是行编号。

5.验证
5.1 验证行编号
SMITH --> AAA
ALLEN --> AAB
不同人名 行号是递增的。
5.2 验证数文件标号
select FILE_ID as fid,FILE_NAME from dba_data_files where TABLESPACE_NAME='USERS' ;
FID FILE_NAME
---------- ---------------------------------------------
4 D:\APP\WANGXUWEI\ORADATA\ORCL\USERS01.DBF
FILE_ID=4,就是ROWID中AAE。
5.3 验证数据库对象编号
select * from dba_objects where object_name='EMP';
objectid
73196
73196 = AAAR3s ???
select ascii('R')-ascii('A') from dual;
R=17=17×64×64

3=26+26+3=55
select ascii('s')-ascii('a')+26 from dual;
s=44
AAAR3s=17×64×64+55×64+44
select 17*64*64+55*64+44 from dual;
73196

5.4 验证块编号
select * from dba_extents where segment_name='EMP';
extent_id =0
file_id =4
block_id =144
bytes =65536
blocks =8
144 = AAAACX ???
select ascii('X')-ascii('A') from dual;
23
AAAACX=2×64+23=
select 2*64+23 from dual;
151
AAAACX=151<>144 ???

6.dbms_rowid包
通过dbms_rowid包,可以直接得到具体的rowid包含的信息:
select dbms_rowid.rowid_object(rowid) object_id,
dbms_rowid.rowid_relative_fno(rowid) file_id,
dbms_rowid.rowid_block_number(rowid) block_id,
dbms_rowid.rowid_row_number(rowid) row_number,
rowid,emp.*
from emp;

通过dbms_rowid包,还可以查询到表或记录所在的文件
select file_id,file_name from dba_data_files
where file_id in (select distinct dbms_rowid.rowid_relative_fno(rowid) from scott.emp);
file_id file_name
4 D:\APP\ORADATA\ORCL\USERS01.DBF

Oracle_高级功能(2) 索引的更多相关文章

  1. Oracle_高级功能(9) 性能优化

    1.oracle优化器 优化目标分为4种: choose (选择性) rule (基于规则) first rows(第一行) all rows(所有行) Description:描述sql的执行计划 ...

  2. Oracle_高级功能(7) 数据字典视图和动态性能视图

    oracle数据字典 1.概念数据字典是oracle数据库用来存储数据库结构信息的地方.数据字典是用来描述数据库数据的组织方式的,由表和视图组成.数据字典基表是在任何 Oracle 数据库中创建的第一 ...

  3. Oracle_高级功能(6) 分区

    oracle分区表1.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区. 表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上 ...

  4. Oracle_高级功能(5) 用户、角色、权限

    一.用户(模式)1.定义用户:对数据库的访问,需要以适当用户身份通过验证,并具有相关权限来完成一系列动作模式(schema):是某个用户所拥有的对象的集合.具有创建对象权限并创建了对象的用户称为拥有某 ...

  5. Oracle_高级功能(4) 数据库存储结构

    数据库存储结构分为:物理存储结构和逻辑存储结构.物理结构和逻辑结构分开,对物理数据的存储不会影响对逻辑结构的访问.1.物理存储结构 数据库文件 os block2.逻辑存储结构 tablespace ...

  6. Oracle_高级功能(8) 事务和锁

    Oracle数据库事务1. 事务定义在数据库中事务是工作的逻辑单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个工作单元 ...

  7. Oracle_高级功能(10) 备份恢复

    备份与恢复Oracle数据库有三种标准的备份方法,分别是导出/导入(EXP/IMP).热备份和冷备份.导出/导入是一种逻辑备份,冷备份和热备份是物理备份.一.导出/导入(Export/Import)利 ...

  8. Oracle_高级功能(3) synonym和database link

    一.同义词synonymconnect sys/123 as sysdba;select * from emp;ORA-00942: 表或视图不存在create synonym emp for sco ...

  9. Oracle_高级功能(1) 数据库设计

    1.三范式规范化关系模式称为范式.第一范式:在一个关系模型R中,如果R的每一个属性的值域中的值都是不可再分的最小数据单位, 则称R为第一范式(1NF).第二范式:如果一个关系模型R属于1NF,并且R的 ...

随机推荐

  1. java实现excel表格导出

    Java 实现导出excel表 POI 1.首先下载poi-3.6-20091214.jar,下载地址如下: http://download.csdn.net/detail/evangel_z/389 ...

  2. Hibernate学习笔记2.1(Hibernate基础配置)

    Hibernate基础配置 1.<property name="hbm2ddl.auto">update</property> 在SessionFactor ...

  3. 吴裕雄 13-MySQL UPDATE 查询

    以下是 UPDATE 命令修改 MySQL 数据表数据的通用 SQL 语法:UPDATE table_name SET field1=new-value1, field2=new-value2[WHE ...

  4. tensorflow 之tensorboard 对比不同超参数训练结果

    我们通常使用tensorboard 统计我们的accurate ,loss等,并绘制曲线,通常是使用一次训练中的, 但是,机器学习中通常要对比不同的 ‘超参数’给模型训练和预测能力的不同这时候如何整合 ...

  5. 安装 gradle

    Gradle是一种现在很流程的构建工具,目前基本和Maven平分天下,而且大有取而代之的趋势.这篇教程教大家怎么在linux上安装Gradle. 一.获得一台linux服务器 要在linux下安装gi ...

  6. 05_ssm基础(六)之SpringMVC

    36.springMVC之入门 1.springMVC简介 Spring MVC是基于MVC模式的一个Web框架,它解决WEB开发中常见的问题(参数接收.文件上传.表单验证.国际化.等等),而且使用简 ...

  7. AutoIncrement无法设置的问题

    [AutoIncrement无法设置的问题] 下图红色处始终无法勾选Auto_Increment 解决方法是在详细列表里勾选. 链接:http://stackoverflow.com/question ...

  8. Unity中的四个路径

    Application.database:当前工程的Assets文件夹(编辑器) Application.StreamingAssets:IO流路径 当前工程的StreamingAssets文件夹(编 ...

  9. javolution学习--介绍

    javolution提供一个高性的Java集合(collection )类库和一些实用的工具类.虽然这个类包只提供非常少的几个集合类,但是这些类就能够代替大部分java.util类.javolutio ...

  10. JMeter学习(七)聚合报告之 90% Line 正确理解(转载)

    转载自 http://www.cnblogs.com/yangxia-test 90% Line 参数正确的含义: 虽然,我的上面理解有一定的道理,显然它是错误的.那看看JMeter 官网是怎么说的? ...