ORACLE什么时候进行全表扫描

来源:互联网 发布:网络教育文凭 编辑:程序博客网 时间:2024/06/04 19:55

本文转载自:http://zhidao.baidu.com/link?url=2nyx4Wem2hUsTNDZepDLy3B7fOVxvufr8UqZWeDjuREJ8oWSxwwLP8LTo63S5bybbEmU1S2KeP4c9BH7Qd4b1_

问:

语句select * from user where username='test'。(没有索引)
1、如果该记录在数据库表(user)的第一条。在oracle中是不是就不会再去查询下面的记录?还是把表中的所有记录加载到缓存中再进行过滤?
2、如果username这个字段有索引的话,情况又是什么样子?

 

答:

1、如果该记录在数据库表(user)的第一条。在oracle中是不是就不会再去查询下面的记录?还是把表中的所有记录加载到缓存中再进行过滤?

答: 因为没有索引, Oracle 不知道 满足 username='test' 条件的, 总共有多少个, 所以全表还是要继续的。

2、如果username这个字段有索引的话,情况又是什么样子?
如果是 RBO (基于规则的优化), 那么自动强制使用索引。
也就是先去索引那里找, 有哪些索引记录是 username='test' 的。
通过这些索引的 信息,拿到相关的 行的 物理位置的ID。
然后再通过这些 行的物理位置的ID, 去表里面,提取出相应的行。返回。

如果是 CBO(基于成本的优化),那么首先分析,索引有没有使用的价值。
例如一百万条记录里面, 只有10个 username='test' 的记录,那么Oracle 将使用这个索引。(使用索引的操作步骤,同RBO)
假如一百万条记录里面,有50万条记录的username='test' 的记录,那么Oracle 发现使用索引,产生的工作量,比全表扫描还慢,因为要读取50W条索引,+50W条记录。于是就会选择直接全表扫描,不使用索引。

 

问:

全表扫描是在数据库文件中进行的吗,还是加载到某个地方进行的?
如果存在索引,默认是RBO还是CBO,又如何进行设置?

 

答:

全表扫描, 看你那个表有多大
表如果小的话,  可能上次检索过, 还在内存缓冲区域里面的话, 可能文件都不需要读取.
如果缓存里面没有,那么就去读取物理文件.
表如果很大的话, 那么缓存里面肯定是不够的,那就必须去读取物理文件了.

Oracle 9的时候,(Oracle 10 / 11 没仔细测试过)
默认是使用 RBO, 也就是默认使用 基于规则的优化。
假如你对表进行了分析。
例如下面这一类型的语句
analyze table user  compute statistics

那么,当 SELECT * FROM user  WHERE username='test' 的时候。
Oracle 会检测到 user 表上面,有统计信息。
这种情况下, Oracle 将自动切换到 使用 CBO 的优化策略。

当然了,使用 CBO,就是要周期的更新统计信息。
否则会出现 统计信息 与 实际信息不匹配的情况。

例如 统计信息里面,可能记录着,这个表有100W条记录,username='test' 的记录只有10条
但是可能经过多次 INSERT/UPDATE后,username='test' 的记录已经有 20W条了。
但是统计信息里面,还是只有10条。
那么在查询的时候, Oracle 看到统计信息的数据,就去使用索引了。
结果嘛......

0 0
原创粉丝点击