• 数据查找方式


    Full Table Scan

    当查询条件无法命中任何索引、或者扫描索引的代价大于全表扫描代价的某一比例时(由参数optimizer_index_cost_adj设定),Oracle会采用全表扫描的方式查找数据。当发生全表扫描时,Oracle会自下向上一次读取一定数量(由参数db_file_multiblock_read_ count设定)的数据块,一直读取到高水位标志(HWM,High Water Mark)下。Full Table Scan会引起db file scattered read事件。

    INDEX UNIQUE SCAN

    全表扫描查找数据的效率是非常低的。而索引能大幅提高查找效率。普通索引的数据结构是B-Tree,树的叶子节点中包含数据的ROWID,指向数据记录,同时还有指针指向前一个/后一个叶子节点。索引扫描每次读取一个数据块,索引扫描是“连续的”(Sequential)。当索引为UNIQUE索引时,每个叶子节点只会指向一条数据。如果Oracle能预知扫描结果只有0或1条记录时,会采用INDEX UNIQUE SCAN。当对Unique Index中的所有字段进行完全匹配时,会发生INDEX UNIQUE SCAN。 

    INDEX UNIQUE SCAN的查找过程如下:

    从数的根节点数据块开始查找:

    1.   查找根节点块中所有key值中大于或等于要查找的值的最小key值;

    2.   如果key值大于查找值,则继续查找这个key值之前一个key值所指向的子节点数据块;

    3.   如果key值等于查找值,则继续查找这个key值所指向的子节点数据块;

    4.   如果没有key值大于或等于查找值,则继续查找最大key值所指向的子节点数据块;

    5.   如果继续查找的节点数据块是数一个分支节点,则重复2~4步;

    6.   如果查找的节点是叶子节点数据块,则在数据块中查找等于查找值的key值;

    7.   如果找到相等的key值,则返回数据和ROWID;

    8.   如果没找到相等的key值,则说明没有符合条件的数据,返回NULL。

    INDEX RANGE SCAN

    如果通过索引查找数据时,Oracle认为会返回数据可能会大于1,会进行INDEX RANGE SCAN,例如Unique Index中字段不完全匹配查找时、非Unique Index查找时。

    INDEX RANGE SCAN分为闭包(有前后查找边界)和非闭包(只有一边或者没有边界)。返回数据会依据索引增序排序,多个相同值则会按照ROWID的增序排序。以下的查找条件都是闭包的:

    WHERE column = 'Value'

    WHERE column like 'value%'

    WHERE column between 'value1' and 'value2'

    WHERE column in ('value1', 'value2')

    以下查找条件非闭包:

    WHERE column < 'value1'

    WHERE column > 'value2'

     闭包条件下的INDEX RANGE SCAN的查找过程如下:

    1.  从数的根节点数据块开始查找;

    2.  查找根节点块中所有key值中大于或等于要查找的起始值的最小key值;

    3.  如果key值大于起始值,则继续查找这个key值之前一个key值所指向的子节点数据块;

    4.  如果key值等于起始值,则继续查找这个key值所指向的子节点数据块;

    5.  如果没有key值大于或等于起始值,则继续查找最大key值所指向的子节点数据块;

    6.  如果继续查找的节点数据块是数一个分支节点,则重复2~4步;

    7.  如果查找的节点是叶子节点数据块,则在数据块中大于或等于要查找的起始值的最小key值;

    8.  如果Key值小于或等于结束值,则:如果所有Key字段都符合WHERE字句中的查找条件,则返回数据和ROWID;否则继续查找当前叶子节点所指向的右边的叶子节点。

     INDEX UNIQUE SCAN和INDEX RANGE SCAN都会引起db file sequential read事件。

    TABLE ACCESS BY INDEX ROWID

    当发生索引扫描时,如果需要返回的字段都在索引上,则直接返回索引上的数据,而如果还需要返回非索引上的字段的值,Oracle则需要根据从索引上查找的ROWID到对应的数据块上取回数据,这时就是TABLE ACCESS BY INDEX ROWID。

    INDEX FAST FULL SCAN & INDEX FULL SCAN

    索引快速全扫描和全表扫描类似,一次读取db_file_multiblock_read_count个数据块来描所有索引的叶子节点。INDEX FAST FULL SCAN和其他索引扫描不同,它不会从树的根节点开始读取,而是直接扫描所有叶子节点;也不会一次读取一个数据块,而是一次读取db_file_multiblock_read_count个数据块。INDEX FAST FULL SCAN会引起db file scattered read事件。

        在某些情况下,如db_file_multiblock_read_count值过小、强制使用索引扫描时,会发生INDEX FULL SCANINDEX FULL SCANINDEX FAST FULL SCAN不同,它是一种索引扫描,按照B-Tree的查找法从树的根节点开始扫描,遍历整棵树,并且一次读取一个数据块。它会引起db file sequential read事件






  • 相关阅读:
    集线程池应用、多次HttpWebRequest请求,自动切换账号等等的移动信息查询软件
    PropertyGrid实现文件选择项
    git通过命令忽略指定文件
    【转】一张图解析FastAdmin中的表格列表的功能
    一张图解析FastAdmin中的FormBuilder表单生成器
    1140 In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'football.order.id'; this is incompatible with sql_mode=only_full_group_by
    centeros 安装mysql
    Flask 教程 第二十三章:应用程序编程接口(API)
    Flask 教程 第二十二章:后台作业
    Flask 教程 第二十一章:用户通知
  • 原文地址:https://www.cnblogs.com/longjshz/p/4286809.html
Copyright © 2020-2023  润新知