Oracle_高级功能(2) 索引

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

原文地址:https://www.cnblogs.com/BradMiller/p/9279753.html

时间: 2024-10-29 02:53:50

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

Oracle_高级功能(6) 分区

oracle分区表1.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区. 表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上), 这样查询数据时,不至于每次都扫描整张表. 2.表分区的具体作用 Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处. 通常,分区可以使某些查询以及维护操作的性能大大提高. 此外,分区还可以极大简化常见的管理任务,分区是构建千兆

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

一.用户(模式)1.定义用户:对数据库的访问,需要以适当用户身份通过验证,并具有相关权限来完成一系列动作模式(schema):是某个用户所拥有的对象的集合.具有创建对象权限并创建了对象的用户称为拥有某个模式注意:创建数据库对象(视图,表等)的任一用户都拥有一个与该用户名称相同的模式,且被视为模式用户. 2.用户分类:用户分为:系统预定义用户.自定义用户.系统预定义用户包括: sys用户,缺省始终创建,且未被锁定,拥有数据字典及其关联的所有对象 system用户,缺省始终创建,且未被锁定,可以访问

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

oracle数据字典 1.概念数据字典是oracle数据库用来存储数据库结构信息的地方.数据字典是用来描述数据库数据的组织方式的,由表和视图组成.数据字典基表是在任何 Oracle 数据库中创建的第一批对象.所有数据库的数据字典表和视图都存储在SYSTEM表空间中.由于当数据库打开时,SYSTEM 表空间始终处于联机状态 ,所以当数据库打开时,数据字典总是可用的.Oracle数据库的SYS用户,拥有数据字典中的所有基表和用户可访问视图.数据字典基表中的数据,对于Oracle 数据库发挥正常功能是

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

数据库存储结构分为:物理存储结构和逻辑存储结构.物理结构和逻辑结构分开,对物理数据的存储不会影响对逻辑结构的访问.1.物理存储结构 数据库文件 os block2.逻辑存储结构 tablespace 表空间 segment 段 extend 扩展区 db block 数据块(8k)2.1创建表空间create tablespace <ts_name> datafile '<file>' size <n> reuse autoextend on next <n>

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

备份与恢复Oracle数据库有三种标准的备份方法,分别是导出/导入(EXP/IMP).热备份和冷备份.导出/导入是一种逻辑备份,冷备份和热备份是物理备份.一.导出/导入(Export/Import)利用Export可将数据从数据库中提取出来,利用Import则可将提取出来的数据送回到Oracle数据库中去.数据导入(Import)的过程是数据导出(Export)的逆过程,分别将数据文件导入数据库和将数据库数据导出到数据文件. 1.全量导出数据(Export)和导入数据(Import)Oracle

[渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序使用高级功能

这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第十二篇:为ASP.NET MVC应用程序使用高级功能 原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 译文版权所有,谢绝全文转载--但您可以在您的网站上添加到该教程的链接. 在之前的教程中,您已经实现了继承.本教程引入了当你在使用实体框架Code

阿里云移动端播放器高级功能---视频下载

基本介绍优酷.爱奇艺.腾讯等主流的视频类App都有视频离线下载的功能,主要目的是在wifi下将视频离线在本地,然后在无网或者4G的情况下去观看离线视频.那么阿里云播放器也提供了视频下载的功能.这个功能主要针对的是点播视频,也就是vid播放的视频的下载. 主要问题m3u8如何下载?我们知道m3u8是一个索引文件,真正的视频文件是各个ts的分片,那么如何下载成一个完成的视频呢?如何对视频下载进行多线程控制?在一些app中,多个视频同时下载被认为是高级VIP才有的功能.如何实现断点续传?当在下载过程中

PHP命名空间规则解析及高级功能

日前发布的PHP 5.3中,最重要的一个新特性就是命名空间的加入.本文介绍了PHP命名空间的一些术语,其解析规则,以及一些高级功能的应用,希望能够帮助读者在项目中真正使用命名空间. 在这里中我们介绍了PHP命名空间的用途和namespace关键字,在这篇文章中我们将介绍一下use命令的使用以及PHP如何解析命名空间的名字的. 为了便于对比,我定义了两个几乎一样的代码块,只有命名空间的名字不同. < ?php // application library 1 namespace App\Lib1;

block高级功能

/* -*- c++ -*- */ /* * Copyright 2004,2007,2009,2010,2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License a