请问在什么情况下全表扫描比索引扫描效率更高?

lovebelobe 2015-10-18 05:43:51
有位先生举了这样一个例子:
假设一张表含有10万行数据--------100000行
我们要读取其中20%(2万)行数据----20000行
表中每行数据大小80字节----------80bytes
数据库中的数据块大小8K----------8000bytes
所以有以下结果:
每个数据块包含100行数据---------100行
这张表一共有1000个数据块--------1000块

通过索引读取20000行数据 = 约20000个table access by rowid = 需要处理20000个块来执行这个查询
但是,请大家注意:整个表只有1000个块!
所以:如果按照索引读取全部的数据的20%相当于将整张表平均读取了20次!!So,这种情况下直接读取整张表的效率会更高。

通过索引读取20000行数据~需要处理20000个块来执行这个查询》
⇒为什么要20000个数据块来执行这个查询?不是1个数据块有100行数据吗?
如果按照索引读取全部的数据的20%相当于将整张表平均读取了20次!!》
⇒这个就更加不理解了,为什么相当于读取了20次……?

各位大大可以帮我解释一下吗?或者有更好的例子的话请不吝赐教!

原帖主人好像休息很久了联系不上,下面的链接是原帖地址:
原帖地址:http://blog.itpub.net/519536/viewspace-612715/
...全文
2350 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lusklusklusk 2016-11-07
  • 打赏
  • 举报
回复
感觉itpub版主原文中没有说清楚条件 通过索引读取20000行数据 = 约20000个table access by rowid = 需要处理20000个块来执行这个查询 按这个逻辑,以后只要索引读取行数大于整表的块数,那都是全表扫描了 个人不认同这样的看法 如果20%的数据分布极度离散,如这20%集中在整张表的1000个块上,那回表20000次也就是索引块+1000块>整表块数,肯定走全表扫描,这点我不否认。 但是要考虑这20%的数据的分布的离散程度,如这20%集中在前面的20%的块,也就是集中在前面的200块,那回表20000次也就是索引块+200块,索引块+200如果小于1000块,那走索引索引扫描啊,这个个人经历实验过的啊。 因为用户所需要的并不是整个块,而是块中的行.从buffer cache的块中读取行的过程,就是逻辑读.就算回表20000次要读取20000次块,但是这并不是不同的20000个块啊
principl 2016-10-25
  • 打赏
  • 举报
回复
引用 1 楼 sjcss 的回复:
1.通过索引去读数据,在索引中找到一个键值,然后这个键值对应的rowid去读表数据,rowid只对应一条记录,所以读一个块也只是为了找到对应rowid的那条记录,所以一次在一个块中只读一条记录。这样当然需要读20000次了,也就是要20000个块。 2.第一个问题理解了,第二个就好算了,20000次需要20000个块 除以 表总共有1000个块就是20
这里有一个问题,可能没有描述清楚。我想如下大部分人可能能理解: 通过索引读取20000行数据,这些数据分布在1000个数据块中。因为索引每次定位一个数据行,所以访问20000行数据相当于我们访问了20000个数据块,这个应该好理解。 通过全表扫描,我们顺序访问1000个数据块,相当于访问了1000个数据块。 看起来索引方法是访问20000个数据块,而全表方法是访问了1000个数据块。 但是索引方法在访问数据块的时候每次读取1条数据,而全表法可能每次访问会读取多条数据。 具体的效率差异,我想可能是在:找数据块的时间。索引再快他也比全表法,多了19000次块的定位操作。而全表法仅仅是扫描读取,没有额外的定位操作,因此这种情况下索引法比全表法要慢。 不知道我的理解对不。
lovebelobe 2015-11-01
  • 打赏
  • 举报
回复
引用 1 楼 sjcss 的回复:
1.通过索引去读数据,在索引中找到一个键值,然后这个键值对应的rowid去读表数据,rowid只对应一条记录,所以读一个块也只是为了找到对应rowid的那条记录,所以一次在一个块中只读一条记录。这样当然需要读20000次了,也就是要20000个块。 2.第一个问题理解了,第二个就好算了,20000次需要20000个块 除以 表总共有1000个块就是20
谢谢你的热心回答!
美到心痛 2015-10-18
  • 打赏
  • 举报
回复
在cbo中,走全表和走索引是靠成本计算出来的,可参考: http://blog.itpub.net/28539951/viewspace-1655342/ http://blog.itpub.net/28539951/viewspace-1664649/
美到心痛 2015-10-18
  • 打赏
  • 举报
回复
1.通过索引去读数据,在索引中找到一个键值,然后这个键值对应的rowid去读表数据,rowid只对应一条记录,所以读一个块也只是为了找到对应rowid的那条记录,所以一次在一个块中只读一条记录。这样当然需要读20000次了,也就是要20000个块。 2.第一个问题理解了,第二个就好算了,20000次需要20000个块 除以 表总共有1000个块就是20

17,082

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧