本章讲述了RQACLE里的访问和连接方法
一、全表扫描访问方法
1.全表扫描就是获取表中所有数据块,再根据条件进行过滤
# 是否使用全表扫描与所要获取的数据在物理数据块上的分布情况有关,而不全决定于获取的数据量的大小
#全表扫描可使用多块读取(连续的多个数据块)来提升速度,,但是读取多个数据块还是一个数据块要看内存中和物理磁盘中数据块的分布来决定。
例如,总共有10个数据块,其中1、3、5、7、9在内存中,则进行全表扫描时因为要读取的数据块不连续故要读取5次,每次只能读取一个数据块。
#低高水位线
表中有数据写入的最后一个数据块称作高水位线,但是数据块中数据的进行更新删除时,高水位线可能并不改变,故假设本来有10个数据块,高水位线在第
十个块上,经过长期的CRUD操作,后九个块已经没有数据了,但是高水位线仍然是在第十个块上,这样全表扫描时就要把十个数据块全部读取并扫描
二、索引扫描访问方法
0. 聚簇因子
聚簇因子记录了索引值相同的数据行是否存存放在同一个或连续的一系列数据块中,或者数据行是否被分散的放在表的多个数据块里。
1. 索引扫描至少需要读取两个块,一个索引块、一个数据块
#索引块中存放着索引列的列值和行编号等信息
行编号中包含改行记录所在的块地址和该行记录在其所在块中的地址
索引默认按B+树存储,也就是说,有可能树不止一层,访问数据时要读取的数据块不止要读取一个索引块
2.索引扫描类型
#索引唯一扫描
谓词部分包含唯一性索,过滤条件是=时使用
#索引范围扫描
SQL谓词部分索引相关过滤条件是> , <,between等范围相关的表达式时使用索引范围扫描。
#索引全扫描
@ 使用场合:
当没有谓语但是所需获取列的列表可以通过其中一列的索引来获得时
当谓语中包含一个位于索引中非引导列上的条件
当数据可以通过一个排过序的索引来获取并会省去单独排序的步骤
@要扫描索引中每一个索引叶子块,获取行编号,取出数据行。比全表扫描快的原因在于通常一个索引块比一个数据块含有更多的条目, 从而总的需要访问的块数
也就较少。
@关于索引全扫描的一个优化:
在获取索引列上的最大或最小值时,因为索引是排过序的,所以只需要访问索引的第一个块或最后一个块,这时要访问的块为从根到第一个或最后一个块树中
的 所有块和在索引块中找到的存放最大或最小数据的那个数据块
#索引跳跃扫描
索引被按引导的不同取值分成数个较小的索引,当谓词条件不包含复合索引引导列的条件,且引导列的值时唯一的时,ORACLE会根据这些较小的索引使用索引跳跃
扫描
#索引快速全扫描
@使用索引快速全扫描是,所有索引块被通过多块读取来进行读取。
@使用场合:
在查询列表中所有字段都包含在索引中并且索引中至少具有一列具有非空约束时代替全表扫描
@索引通过索引来访问而不是通过数据块来访问
注:数据块是通过无序的多表读取来读取的,故不能 用来避免排序
三、连接方法:
1. 每个连接方法有两个分支,所访问的第一张表通常称为驱动表,所访问的第二张表通常称为被驱表。优化器根据统计信息和where条件的子句选择返回记录最少的表
做驱动表
2.嵌套循环链接:
# 使用一次访问运算所得到的结果集中的每一行来与另一个表进行对碰。
# 成本主要来源于读取外表的每一行并将其与所匹配的内层表中的行链接需要的成本
# 在结果集较小时比较适用
#eg:
3.排序-合并链接
#排序合并链接要独立的读取需要链接的两张表,对每张表中的数据行(满足where子句中条件的数据行)按照链接键进行排序 ,然后对排序后的数据集进行合并。
#缺点,开销大,对于不能放入内存中的大数据源来说,可能会用到临时磁盘空间来完成排序。
#适合数据筛选条件有限且返回有限数据行的查询,条件为非等式时,排序-合并链接往往是最好的选择
#eg.
3. 散列链接
# 原理:
@用where子句条件过滤单独读要进行链接的两个表,再将读取的数据行较少的表完全散列化到内存中,这个散列表包含原本被基于链接键转化为散列值随机函
数载入散列桶中。内存不足时,散列表将被写入到临时的磁盘空间。
@读取较大的表,对其链接键应用散列函数,和被散列化在内存中的那个表数据所在的散列通进行探测匹配。
每一个散列桶都有一个存放在其中的数据行的列表,这个列表用来和探测行进行匹配,如果匹配则返回这一行记录。
@和嵌套循环链接的区别在于
这里的大表是驱动表,而较小的散列表则被探测多次
@注意:
在这里决定哪个表最小不仅仅取决于行数,还和行的大小有关。因为散列中要存放整个数据行。
只用在相等的情况下
#执行计划
4.笛卡尔积链接
5.外链接
#oracle用+来表示外链接,放在一对括号里,位于只有匹配才会返回行的表的链接条件旁,+号表示外连接只能用于两边表外链接。
#外链接需要外链接表作为驱动表,这意味着可能不能选择更加优化的执行顺序。