通过索引访问表的顺序问题 Oracle通过索引去访问表,那么,就会产生2种方式。1、访问一条索引后,立即通过rowid去访问表。2、访问完所有的索引后,再去通过这些rowid去访问表。请问,Oracle是怎么处理的呢?谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 (1)Oracle的SQL执行之前,有一个所谓的执行计划,实际上是通过分析提交的SQL指令,来分析是采用哪些索引或者进行全表扫描来访问记录。这个取决于你的表索引、SQL的写法以及索引字段的类型等等信息。(2)在进行使用哪条索引判断时,一般会根据你的查询条件列来判断,如果查询列和索引条匹配,则会使用该索引。这里需要说明的是,Oracle此时并没有真正访问表的索引,而是根据表的索引定义列来判断该是否使用它,也就是得到前面提到的执行计划。(3)一旦得到合适的执行计划(包括索引),则开始执行SQL。(4)因此,可以认为你的第一种方式是Oracle的执行方式。 通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。暂时未明确找到文档,应该是再将索引的时候说明的从索引实现和ORACLE的基本原理来看,先访问索引,例如B-TREE索引,访问索引叶子的值是是否在索引范围内,如果是,立刻返回ROWID和对应行的值到内存,因为索引已经是排序好了的,这样继续访问临近的叶子的值是否在范围内,如果在的话,继续返回ROWID和相应行的值到内存,。。 感谢你每次都在深夜回复,谢谢。可是,对于以上解释的内容,我还是有我的疑惑。例如1、对于索引范围扫描和索引全扫描来说,你的这种说法是说得通的,但是我是否可以有另外的一种理解。即,Oracle先一次性全部扫描完所有满足访问条件的叶子节点,然后,再根据叶子中的rowid去访问数据块。2、对于索引快速全扫描,你的这种说法就说不通了。因为它会进行多块(即多叶子块)的读取。难道是会读了多块后,再对块中的rowid,进行一行一行的处理?这样效率太低了吧。请指正,谢谢。 不管走不走索引,oracle的数据访问都是基于rowid一条一条的返回到data buffer cache中的,因为rowid决定了数据在数据库的文件和快的位置,只有对每个rowid进行数据处理和读取,才能返回相应的数据,除非你访问的就是叶子节点的值,如复合主键 走索引的话 ,因为索引本身是排好序的,这样去找的话比较快的定位到需要的ROWID,而不走索引的话,则要按照ROWID的顺序一条一条去判断其中的值进行对比 建议看看http://blog.csdn.net/java3344520/article/details/6969429中的SQL执行原理 走索引的话,是没有错。但是,不走索引的话,例如全表扫描,是不会访问rowid的,因为表中并没有rowid这一列,所以会称其为伪列。全表扫描走的是块的顺序和块中依次出现的行的顺序,只是这个顺序正好就是rowid的顺序。所以说,对于“不走索引”那段描述,结论是对的,但是导出的过程不对。谢谢。 rowid,只是用来定位数据文件中的块号和行号的,从而确定一行数据的物理位置,一旦数据从数据文件中读入到buffer cache中,那么这时rowid就几乎没用了。在buffer cache中行的定位,不再使用rowid,而是使用hash值,只有在hash值匹配的情况下,才去查看rowid是否匹配。所以,这不会妨碍,把索引一次性全部读取内存中,再一次去访问buffer cache(内存没有命中的情况下,再去物理读。)请多多指教,谢谢。 哪位大哥提供一下pro*c的资料啊?有没有电子版的教材啊? 求CNOUG邀请码 如何在编译一个包的时候跟踪啊? 大家来谈谈三层结构中的中间层是如何应用编写的呢? 求数据库恢复的方法? 取和今天的日期相隔10天的数据的sql怎么写啊,在线等啊 大家好,我搞不懂,为什么我这样的语句,用ms sql做后台数据库,下面运行正常!而换数据库就不行了呢? 菜鸟问题,关于日期格式的 在浏览器中访问oracle (指定主机和目标数据身份证明)失败 如何导出当前库内所有有数据的表的表名 rowid 在两张表上查询效果为什么不同啊。。 求请教。今天考试,考的是我门没怎么学过的oracle数据库的知识。
(2)在进行使用哪条索引判断时,一般会根据你的查询条件列来判断,如果查询列和索引条匹配,则会使用该索引。这里需要说明的是,Oracle此时并没有真正访问表的索引,而是根据表的索引定义列来判断该是否使用它,也就是得到前面提到的执行计划。
(3)一旦得到合适的执行计划(包括索引),则开始执行SQL。
(4)因此,可以认为你的第一种方式是Oracle的执行方式。
感谢你每次都在深夜回复,谢谢。可是,对于以上解释的内容,我还是有我的疑惑。例如
1、对于索引范围扫描和索引全扫描来说,你的这种说法是说得通的,但是我是否可以有另外的一种理解。
即,Oracle先一次性全部扫描完所有满足访问条件的叶子节点,然后,再根据叶子中的rowid去访问数据块。2、对于索引快速全扫描,你的这种说法就说不通了。
因为它会进行多块(即多叶子块)的读取。难道是会读了多块后,再对块中的rowid,进行一行一行的处理?这样效率太低了吧。请指正,谢谢。
http://blog.csdn.net/java3344520/article/details/6969429
中的SQL执行原理
走索引的话,是没有错。但是,不走索引的话,例如全表扫描,是不会访问rowid的,因为表中并没有rowid这一列,所以会称其为伪列。全表扫描走的是块的顺序和块中依次出现的行的顺序,只是这个顺序正好就是rowid的顺序。所以说,对于“不走索引”那段描述,结论是对的,但是导出的过程不对。谢谢。
rowid,只是用来定位数据文件中的块号和行号的,从而确定一行数据的物理位置,
一旦数据从数据文件中读入到buffer cache中,那么这时rowid就几乎没用了。
在buffer cache中行的定位,不再使用rowid,而是使用hash值,
只有在hash值匹配的情况下,才去查看rowid是否匹配。所以,这不会妨碍,把索引一次性全部读取内存中,再一次去访问buffer cache(内存没有命中的情况下,再去物理读。)请多多指教,谢谢。