Oracle通过索引去访问表,那么,就会产生2种方式。1、访问一条索引后,立即通过rowid去访问表。
2、访问完所有的索引后,再去通过这些rowid去访问表。请问,Oracle是怎么处理的呢?谢谢

解决方案 »

  1.   

    (1)Oracle的SQL执行之前,有一个所谓的执行计划,实际上是通过分析提交的SQL指令,来分析是采用哪些索引或者进行全表扫描来访问记录。这个取决于你的表索引、SQL的写法以及索引字段的类型等等信息。
    (2)在进行使用哪条索引判断时,一般会根据你的查询条件列来判断,如果查询列和索引条匹配,则会使用该索引。这里需要说明的是,Oracle此时并没有真正访问表的索引,而是根据表的索引定义列来判断该是否使用它,也就是得到前面提到的执行计划。
    (3)一旦得到合适的执行计划(包括索引),则开始执行SQL。
    (4)因此,可以认为你的第一种方式是Oracle的执行方式。
      

  2.   

    通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。暂时未明确找到文档,应该是再将索引的时候说明的从索引实现和ORACLE的基本原理来看,先访问索引,例如B-TREE索引,访问索引叶子的值是是否在索引范围内,如果是,立刻返回ROWID和对应行的值到内存,因为索引已经是排序好了的,这样继续访问临近的叶子的值是否在范围内,如果在的话,继续返回ROWID和相应行的值到内存,。。
      

  3.   


    感谢你每次都在深夜回复,谢谢。可是,对于以上解释的内容,我还是有我的疑惑。例如
    1、对于索引范围扫描和索引全扫描来说,你的这种说法是说得通的,但是我是否可以有另外的一种理解。
    即,Oracle先一次性全部扫描完所有满足访问条件的叶子节点,然后,再根据叶子中的rowid去访问数据块。2、对于索引快速全扫描,你的这种说法就说不通了。
    因为它会进行多块(即多叶子块)的读取。难道是会读了多块后,再对块中的rowid,进行一行一行的处理?这样效率太低了吧。请指正,谢谢。
      

  4.   

    不管走不走索引,oracle的数据访问都是基于rowid一条一条的返回到data buffer cache中的,因为rowid决定了数据在数据库的文件和快的位置,只有对每个rowid进行数据处理和读取,才能返回相应的数据,除非你访问的就是叶子节点的值,如复合主键
      

  5.   

    走索引的话 ,因为索引本身是排好序的,这样去找的话比较快的定位到需要的ROWID,而不走索引的话,则要按照ROWID的顺序一条一条去判断其中的值进行对比
      

  6.   

    建议看看
    http://blog.csdn.net/java3344520/article/details/6969429
    中的SQL执行原理
      

  7.   


    走索引的话,是没有错。但是,不走索引的话,例如全表扫描,是不会访问rowid的,因为表中并没有rowid这一列,所以会称其为伪列。全表扫描走的是块的顺序和块中依次出现的行的顺序,只是这个顺序正好就是rowid的顺序。所以说,对于“不走索引”那段描述,结论是对的,但是导出的过程不对。谢谢。
      

  8.   


    rowid,只是用来定位数据文件中的块号和行号的,从而确定一行数据的物理位置,
    一旦数据从数据文件中读入到buffer cache中,那么这时rowid就几乎没用了。
    在buffer cache中行的定位,不再使用rowid,而是使用hash值,
    只有在hash值匹配的情况下,才去查看rowid是否匹配。所以,这不会妨碍,把索引一次性全部读取内存中,再一次去访问buffer cache(内存没有命中的情况下,再去物理读。)请多多指教,谢谢。