ORACLE什么时候进行全表扫描
2014-06-13 16:16
274 查看
本文转载自: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 看到统计信息的数据,就去使用索引了。
结果嘛......
问:
语句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 看到统计信息的数据,就去使用索引了。
结果嘛......
相关文章推荐
- oracle是如何进行全表扫描实验
- oracle优化:避免全表扫描
- oracle优化之count的优化-避免全表扫描
- oracle CBO优化器何时会选择全表扫描
- 【Oracle】取得数据库全表扫描的语句(get_fullscan_table)
- Oracle SQL优化必要的全表扫描思路分析
- oracle全表扫描的优化
- oracle全表扫描166G的表只花了6分钟
- Oracle 全表扫描及其执行计划(full table scan)
- oracle优化:避免全表扫描
- oracle 11.2.0.3全表扫描COST计算(非工作量模式)
- Oracle的大表,小表与全表扫描
- Oracle 索引 避免全表扫描
- oracle优化全表扫描和索引使用
- 2013.11.1全表扫描 flush"oracle的缓存 SQL递归语句
- Oracle 11g全表扫描以Direct Path Read方式执行
- Oracle 设置在全表扫描时跳过损坏的数据块
- oracle 优化,全表扫描
- Oracle 全表扫描及其执行计划(full table scan)
- Oracle避免全表扫描方式